<template>
  <div class="map-container" ref="gisMap">
    <l-map ref="myMap" :zoom="zoom" :center="center" @update:zoom="updateZoomLevel">
      <l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
      <!-- 渲染坐标点 -->
      <l-marker 
        v-for="point in points" 
        :key="point.id" 
        :lat-lng="[point.lat, point.lng]"
        @click="handleMarkerClick(point)">
        <l-popup>
          <div>
            <h3>{{ point.name }}</h3>
            <p>{{ point.description }}</p>
          </div>
        </l-popup>
      </l-marker>
      
      <!-- 渲染线路 -->
      <template v-for="(route, index) in routes">
        <!-- 线路 -->
        <l-polyline 
          :key="'route-' + index" 
          :lat-lngs="route.coordinates" 
          :color="route.color" 
          :weight="route.weight || 3" 
          :dash-array="route.dashArray" 
          :opacity="route.opacity || 0.8">
          <l-popup>
            <div>
              <h3>{{ route.name }}</h3>
              <p>{{ route.description }}</p>
            </div>
          </l-popup>
        </l-polyline>
        
        <!-- 塔杆节点 -->
        <l-marker 
          v-for="(coord, coordIndex) in route.coordinates" 
          :key="'tower-' + index + '-' + coordIndex" 
          :lat-lng="coord"
          :icon="towerIcon">
          <l-popup>
            <div>
              <h3>{{ route.name }}</h3>
              <p>{{ route.towerNames && route.towerNames[coordIndex] ? route.towerNames[coordIndex] : '塔杆节点' }}</p>
            </div>
          </l-popup>
        </l-marker>
      </template>
      
      <!-- 其他自定义图层 -->
      <l-polyline :lat-lngs="lineCoordinates" color="green"></l-polyline>
    </l-map>
    
    <!-- 显示/隐藏地图控制按钮 -->
    <button class="map-controls-toggle" @click="toggleMapControls">
      {{ showMapControls ? '隐藏控制' : '显示控制' }}
    </button>
    
    <!-- 添加示例组件 -->
    <route-example v-if="showRouteExample && showMapControls" />
    
    <!-- 示例控制按钮 -->
    <button class="route-example-toggle" @click="toggleRouteExample" v-if="showMapControls">
      {{ showRouteExample ? '隐藏路线示例' : '显示路线示例' }}
    </button>
    
    <!-- 网络状态指示器 -->
    <div class="network-status" :class="forceOfflineMode ? 'offline' : (isOnline ? 'online' : 'offline')" v-if="showMapControls">
      <span>{{ forceOfflineMode ? '强制离线模式' : (isOnline ? '已连接网络' : '离线模式') }}</span>
      <button class="network-toggle" @click="toggleOfflineMode">
        {{ forceOfflineMode ? '切换为在线模式' : '切换为离线模式' }}
      </button>
    </div>
    
    <!-- 缩放级别显示 -->
    <div class="zoom-info-display" v-if="showMapControls">
      当前缩放级别: <span class="zoom-level">{{ currentDisplayZoom }}</span>
    </div>
    
    <!-- 缓存控制面板开关按钮 -->
    <button class="cache-toggle-button" @click="toggleCachePanel" v-if="showMapControls">
      {{ showCachePanel ? '隐藏缓存控制' : '显示缓存控制' }}
    </button>
    
    <!-- 地图控制面板 -->
    <div class="map-controls" v-show="showCachePanel && showMapControls">
      <div v-if="downloading">
        <div>缓存处理中: {{ progress }}%</div>
        <div class="progress-bar">
          <div class="progress-value" :style="{ width: progress + '%' }"></div>
        </div>
      </div>
      
      <div v-if="!downloading && storedTilesCount === 0" class="cache-hint">
        请先点击下方"保存当前可见区域"按钮缓存
      </div>
      
      <div v-if="storedTilesCount > 0">
        已缓存: {{ storedTilesCount }} 个瓦片
      </div>
      
      <div class="zoom-settings" v-if="!downloading">
        <div class="setting-label">缓存缩放级别范围:</div>
        <div class="zoom-range">
          <span>{{ currentCacheConfig.minZoom }}</span>
          <input 
            type="range" 
            min="10" 
            max="16" 
            v-model.number="currentCacheConfig.minZoom" 
            @change="validateZoomRange"
          >
        </div>
        <div class="zoom-range">
          <span>{{ currentCacheConfig.maxZoom }}</span>
          <input 
            type="range" 
            min="10" 
            max="16" 
            v-model.number="currentCacheConfig.maxZoom"
            @change="validateZoomRange"
          >
        </div>
        <div class="zoom-info">
          级别范围：10(远景)→16(近景)
        </div>
      </div>
      
      <div class="control-buttons">
        <button @click="exportMapCache" :disabled="storedTilesCount === 0" class="action-button">导出缓存</button>
        <label class="upload-button action-button">
          导入缓存
          <input 
            type="file" 
            accept=".json" 
            style="display: none" 
            @change="handleFileUpload"
          >
        </label>
      </div>
      
      <div class="control-buttons" style="margin-top: 10px;">
        <button @click="saveVisibleArea" :disabled="downloading" class="action-button primary">保存当前可见区域</button>
      </div>
      
      <div class="advanced-options" v-if="storedTilesCount > 0">
        <div class="setting-label">高级选项:</div>
        <div class="control-buttons">
          <button @click="repairCache" :disabled="downloading" class="action-button warning">修复损坏缓存</button>
          <button @click="diagnoseCacheIssues" :disabled="downloading" class="action-button info">诊断缓存问题</button>
          <button @click="showCacheMisses" :disabled="downloading" class="action-button info">查看缓存未命中</button>
          <button @click="showCurrentZoom" :disabled="downloading" class="action-button info">打印当前缩放级别</button>
          <button @click="recreateMapLayers" :disabled="downloading" class="action-button info">强制刷新地图</button>
          <button @click="clearCache" :disabled="downloading" class="action-button danger">清除所有缓存</button>
        </div>
      </div>
    </div>
    
    <!-- 线路图例 -->
    <div class="route-legend" v-if="showMapControls || showAlways">
      <h4>线路图例</h4>
      <!-- 动态渲染线路图例 -->
      <div v-for="(route, index) in routes" :key="'legend-' + index" class="legend-item">
        <span class="color-box" :style="{ 'background-color': route.color, height: route.weight + 'px' }"></span>
        <span>{{ route.name }}</span>
      </div>
      <div class="legend-item tower-legend">
        <div class="small-tower-icon">
          <svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16">
            <rect x="5" y="0" width="2" height="16" fill="#333"/>
            <rect x="3" y="3" width="6" height="1" fill="#333"/>
            <rect x="3" y="8" width="6" height="1" fill="#333"/>
            <rect x="3" y="13" width="6" height="1" fill="#333"/>
          </svg>
        </div>
        <span>塔杆位置</span>
      </div>
    </div>
    
    <!-- 线路选择下拉列表 -->
    <div class="route-selector" v-if="showMapControls || showAlways" style="left: 100px;">
      <select v-model="selectedRoute" @change="handleRouteChange" class="route-select">
        <option disabled value="">请选择线路</option>
        <option v-for="(route, index) in routeOptions" :key="index" :value="route">
          {{ route }}
        </option>
      </select>
      <!-- 新增按钮 -->
      <button class="add-route-btn" @click="showAddRouteDialog" title="新增线路">
        新增
      </button>
      <!-- 删除按钮 -->
      <button 
        class="delete-route-btn" 
        @click="deleteSelectedRoute" 
        title="删除选中线路"
        :disabled="!selectedRoute"
        :class="{ 'disabled': !selectedRoute }"
      >
        删除
      </button>
    </div>
    
    <!-- 新增线路弹出框 -->
    <div class="route-dialog-overlay" v-if="showRouteDialog" @click="closeAddRouteDialog">
      <div class="route-dialog" @click.stop>
        <h3>新增线路</h3>
        
        <!-- 原始线路 -->
        <div class="route-section">
          <div class="route-header">
            <label class="route-label">原始线路名称</label>
            <input 
              type="text" 
              v-model="newRouteData.originalRouteName" 
              placeholder="请输入原始线路名称"
              class="route-input"
            >
          </div>
          
          <div class="coordinate-row">
            <label class="coord-label">经度</label>
            <input 
              type="number" 
              v-model.number="newRouteData.originalRoute.start.lat" 
              placeholder="起点经度"
              class="coord-input"
              step="0.000001"
            >
            <label class="coord-label">纬度</label>
            <input 
              type="number" 
              v-model.number="newRouteData.originalRoute.start.lng" 
              placeholder="起点纬度"
              class="coord-input"
              step="0.000001"
            >
          </div>
          
          <div class="coordinate-row">
            <label class="coord-label">经度</label>
            <input 
              type="number" 
              v-model.number="newRouteData.originalRoute.end.lat" 
              placeholder="终点经度"
              class="coord-input"
              step="0.000001"
            >
            <label class="coord-label">纬度</label>
            <input 
              type="number" 
              v-model.number="newRouteData.originalRoute.end.lng" 
              placeholder="终点经度"
              class="coord-input"
              step="0.000001"
            >
          </div>
        </div>
        
        <!-- 应急迂回线路 -->
        <div class="route-section" v-for="(detourRoute, index) in newRouteData.detourRoutes" :key="index">
          <div class="route-header">
            <label class="route-label">应急迂回线路</label>
            <input 
              type="text" 
              v-model="detourRoute.name" 
              placeholder="请输入应急线路名称"
              class="route-input"
            >
            <!-- 删除按钮 -->
            <button 
              class="delete-route-btn" 
              @click="removeDetourRoute(index)"
              v-if="newRouteData.detourRoutes.length > 1"
              title="删除此应急线路"
            >
              ×
            </button>
          </div>
          
          <div class="coordinate-row">
            <label class="coord-label">经度</label>
            <input 
              type="number" 
              v-model.number="detourRoute.start.lat" 
              placeholder="起点经度"
              class="coord-input"
              step="0.000001"
            >
            <label class="coord-label">纬度</label>
            <input 
              type="number" 
              v-model.number="detourRoute.start.lng" 
              placeholder="起点纬度"
              class="coord-input"
              step="0.000001"
            >
          </div>
          
          <div class="coordinate-row">
            <label class="coord-label">经度</label>
            <input 
              type="number" 
              v-model.number="detourRoute.end.lat" 
              placeholder="终点经度"
              class="coord-input"
              step="0.000001"
            >
            <label class="coord-label">纬度</label>
            <input 
              type="number" 
              v-model.number="detourRoute.end.lng" 
              placeholder="终点纬度"
              class="coord-input"
              step="0.000001"
            >
          </div>
        </div>
        
        <!-- 新增应急线路按钮 -->
        <div class="add-detour-section">
          <button class="add-detour-btn" @click="addDetourRoute">
            +
          </button>
        </div>
        
        <!-- 按钮区域 -->
        <div class="dialog-actions">
          <button class="cancel-btn" @click="closeAddRouteDialog">取消</button>
          <button class="save-btn" @click="saveNewRoute">保存</button>
        </div>
      </div>
    </div>
    
    <!-- 删除确认弹出框 -->
    <div class="route-dialog-overlay" v-if="showDeleteDialog" @click="closeDeleteDialog">
      <div class="delete-dialog" @click.stop>
        <h3>确认删除</h3>
        <p>您确定要删除线路 <strong>"{{ routeToDelete }}"</strong> 吗？</p>
        <p class="warning-text">此操作不可撤销！</p>
        
        <div class="dialog-actions">
          <button class="cancel-btn" @click="closeDeleteDialog">取消</button>
          <button class="confirm-delete-btn" @click="confirmDeleteRoute">确认删除</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { LMap, LTileLayer, LMarker, LPopup, LPolyline } from 'vue2-leaflet';
import 'leaflet/dist/leaflet.css';
import { Icon } from 'leaflet';
import * as L from 'leaflet';
import 'leaflet.offline';
import localforage from 'localforage';
import 'leaflet-polylinedecorator';
import RouteExample from '../components/RouteExample.vue';

// 确保leaflet.offline在Leaflet之后加载并可以访问L对象
// 设置Leaflet图标
delete Icon.Default.prototype._getIconUrl;
Icon.Default.mergeOptions({
  iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
  iconUrl: require('leaflet/dist/images/marker-icon.png'),
  shadowUrl: require('leaflet/dist/images/marker-shadow.png')
});

export default {
  components: {
    LMap,
    LTileLayer,
    LMarker,
    LPopup,
    LPolyline,
    RouteExample
  },
  data() {
    return {
      // 地图初始中心点和缩放级别
      center: [42.01, 125.85], // 调整为更合适的中心点以显示所有线路
      zoom: 11, // 调整缩放级别以显示全部线路
      // 地图瓦片图层
      url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
      attribution: '&copy; OpenStreetMap contributors',
      // 显示地图控制
      showMapControls: false,
      showAlways: true,
      // 坐标点数据
      points: [
        { 
          id: 1, 
          lat: 24.479, 
          lng: 118.089, 
          name: '光缆节点1',
          description: '重要节点' 
        },
        // 更多坐标点...
      ],
      // 线段坐标(如光缆路径)
      lineCoordinates: [
        [24.479, 118.089],
        [24.489, 118.099],
        [24.499, 118.079]
      ],
      // 缓存相关
      tileLayerOffline: null,
      progress: 0,
      downloading: false,
      storedTilesCount: 0,
      offlineControl: null,
      // 缓存级别范围
      minCacheZoom: 10,
      maxCacheZoom: 16,
      // 当前缓存配置  
      currentCacheConfig: {
        minZoom: 10,
        maxZoom: 16
      },
      // 网络状态
      isOnline: navigator.onLine,
      // 强制离线模式
      forceOfflineMode: false,
      // 网络检测计时器
      networkCheckTimer: null,
      // 损坏的缓存项列表
      corruptCacheItems: [],
      // 新增的属性
      hasShownOfflineMissingTilesWarning: false,
      // 缓存未命中的URL列表
      cacheMisses: [],
      // 当前显示的缩放级别
      currentDisplayZoom: 13,
      // 控制缓存面板的显示/隐藏
      showCachePanel: true,
      // 是否已显示自动缓存消息
      hasShownAutoCacheMessage: false,
      
      // 线路数据
      routes: [],
      
      // 原有线路 - 长郑线
      originalRouteCoordinates: [
        [41.78256078, 125.94552766000001],  // 1号塔
        [42.25107994066251, 125.82455263162291]  // 140号塔
      ],
      
      // 应急迂回线路1 - 66kV长三线
      emergencyRoute1Coordinates: [
        [41.780943496, 125.94568483100001],  // 1号塔
        [42.04933731, 125.757032241]  // 218号塔
      ],
      
      // 应急迂回线路2 - 66kV郑三线
      emergencyRoute2Coordinates: [
        [42.251307386, 125.82101946600001],  // 220kV郑家变
        [42.0493135805556, 125.75748983000001]  // 170号塔
      ],
      
      emergencyRoute3Coordinates: [
        [52.251307386, 135.82101946600001],  // 220kV郑家变
        [52.0493135805556, 135.75748983000001]  // 170号塔
      ],
      emergencyRoute4Coordinates: [
        [42.251307386, 125.82101946600001],  // 220kV郑家变
        [42.0493135805556, 125.75748983000001]  // 170号塔
      ],
      emergencyRoute5Coordinates: [
        [42.251307386, 125.82101946600001],  // 220kV郑家变
        [42.0493135805556, 125.75748983000001]  // 170号塔
      ],
      emergencyRoute6Coordinates: [
        [42.251307386, 125.82101946600001],  // 220kV郑家变
        [42.0493135805556, 125.75748983000001]  // 170号塔
      ],
      
      emergencyRoute7Coordinates: [
        [42.251307386, 125.82101946600001],  // 220kV郑家变
        [42.0493135805556, 125.75748983000001]  // 170号塔
      ],
      emergencyRoute8Coordinates: [
        [42.251307386, 125.82101946600001],  // 220kV郑家变
        [42.0493135805556, 125.75748983000001]  // 170号塔
      ],
      
      
      // 自定义塔杆图标
      towerIcon: null,
      
      // 控制路线示例组件的显示/隐藏
      showRouteExample: false,
      
      // 线路选择下拉列表
      selectedRoute: '',
      routeOptions: ['通丰1号线',  '金集甲线', '长郑线', '高梅线',  '高东线'],
      // routeOptions: ['通丰1号线', '通金线', '金集甲线', '长郑线', '高梅线',  '高东线']
      
      // 新增线路相关数据
      showRouteDialog: false,
      newRouteData: {
        originalRouteName: '',
        originalRoute: {
          start: { lat: null, lng: null },
          end: { lat: null, lng: null }
        },
          detourRoutes: [
          {
            name: '',
            start: { lat: null, lng: null },
            end: { lat: null, lng: null }
            }
          ]
        },
      // 删除相关数据
      showDeleteDialog: false,
      routeToDelete: ''
    };
  },
  methods: {
    // 切换地图控制元素的显示/隐藏
    toggleMapControls() {
      this.showMapControls = !this.showMapControls;
    },
    
    // 更新缩放级别显示
    updateZoomLevel(zoom) {
      this.currentDisplayZoom = zoom;
      console.log('[地图] 当前缩放级别:', zoom);
    },
    
    // 公共方法：清除并渲染新的线路
    renderNewRoutes(options) {
      // 清除当前线路上的箭头装饰器
      if (this.routeDecorators) {
        const map = this.$refs.myMap.mapObject;
        this.routeDecorators.forEach(decorator => {
          map.removeLayer(decorator);
        });
        this.routeDecorators = [];
      }
      
      // 清空当前线路
      this.routes = [];
      
      // 渲染新线路
      return this.renderRoutes(options);
    },
    
    handleMarkerClick(point) {
      console.log('点击了标记点:', point);
      // 处理点击事件
    },
    // 从API获取坐标点数据
    async fetchPoints() {
      try {
        const response = await axios.get('/api/gis-points');
        this.points = response.data;
      } catch (error) {
        console.error('获取坐标点数据失败:', error);
      }
    },
    // 高亮显示故障光缆
    highlightFaultyCable(cableId) {
      // 在地图上高亮显示特定光缆
      const cable = this.cables.find(c => c.id === cableId);
      if (cable) {
        // 修改样式或添加动画效果
        this.selectedCable = cable;
        // 可以调整地图视图聚焦到该光缆
        this.$refs.myMap.mapObject.fitBounds(cable.path);
      }
    },
    
    // 显示影响范围
    showImpactArea(point, radius) {
      // 创建圆形范围显示影响区域
      this.impactCircle = L.circle([point.lat, point.lng], {
        color: 'red',
        fillColor: '#f03',
        fillOpacity: 0.3,
        radius: radius * 1000 // 转换为米
      }).addTo(this.$refs.myMap.mapObject);
    },
    
    // 初始化离线地图
    initOfflineMap() {
      const map = this.$refs.myMap.mapObject;
      
      console.log('[地图初始化] 开始初始化离线地图');
      
      // 在初始化时就检查离线状态
      const isOfflineMode = this.forceOfflineMode || !navigator.onLine;
      console.log('[地图初始化] 检测到模式:', isOfflineMode ? '离线模式' : '在线模式',
                 '强制离线:', this.forceOfflineMode, 
                 '浏览器网络状态:', navigator.onLine ? '已连接' : '已断开');
      
      // 使用标准L.TileLayer而不是自定义扩展，避免SVG类操作问题
      console.log('[地图初始化] 创建瓦片图层');
      const tileLayer = L.tileLayer(this.url, {
        attribution: this.attribution,
        subdomains: 'abc',
        minZoom: 10,
        maxZoom: 16
      });
      
      console.log('[地图初始化] 设置网络请求拦截');
      // 拦截并阻止离线模式下的所有瓦片网络请求
      this.interceptNetworkRequests();
      
      // 保存图层引用
      this.tileLayer = tileLayer;
      
      console.log('[地图初始化] 将瓦片图层添加到地图');
      // 添加到地图
      tileLayer.addTo(map);
      
      console.log('[地图初始化] 设置瓦片拦截器');
      // 使用拦截器拦截图片加载请求
      this.setupTileInterceptor(tileLayer, map);
      
      console.log('[地图初始化] 设置自定义缓存功能');
      // 重写加载方法以支持缓存
      this.setupCustomCaching(map, tileLayer);
      
      // 如果在离线模式下，显示状态提示
      if (isOfflineMode) {
        console.log('[地图初始化] 显示离线模式提示');
        this.showMessage('已启用离线模式，使用本地缓存', 'info');
      }
      
      console.log('[地图初始化] 离线地图初始化完成');
    },
    
    // 拦截并阻止网络请求
    interceptNetworkRequests() {
      console.log('[网络拦截] 开始设置网络请求拦截');
      
      // 拦截XMLHttpRequest
      const originalXhrOpen = XMLHttpRequest.prototype.open;
      const self = this;
      
      console.log('[网络拦截] 重写XMLHttpRequest.open方法');
      XMLHttpRequest.prototype.open = function() {
        // 检查是否为地图瓦片请求
        const url = arguments[1];
        if (typeof url === 'string' && url.includes('tile.openstreetmap.org')) {
          // 是地图瓦片请求，检查是否离线模式
          if (self.forceOfflineMode) {
            console.log('[网络拦截] 已阻止离线模式下的XHR请求:', url.substring(0, 40) + '...');
            // 修改为无效URL，阻止请求
            arguments[1] = 'about:blank';
          }
        }
        return originalXhrOpen.apply(this, arguments);
      };
      
      // 拦截Fetch API
      const originalFetch = window.fetch;
      console.log('[网络拦截] 重写Fetch API方法');
      window.fetch = function() {
        const url = arguments[0];
        if (typeof url === 'string' && url.includes('tile.openstreetmap.org')) {
          if (self.forceOfflineMode) {
            console.log('[网络拦截] 已阻止离线模式下的Fetch请求，尝试从缓存加载:', url.substring(0, 40) + '...');
            
            // 尝试从缓存加载瓦片
            return self.loadTileFromCacheForFetch(url)
              .then(cachedData => {
                if (cachedData) {
                  return new Response(cachedData.data, {
                    status: 200,
                    headers: {'Content-Type': 'image/png'}
                  });
                }
                // 缓存中没有找到，返回错误
                return Promise.reject(new Error('离线模式下未找到缓存瓦片'));
              });
          }
        }
        return originalFetch.apply(this, arguments);
      };
      
      // 拦截Image加载
      console.log('[网络拦截] 重写HTMLImageElement.src设置器');
      const originalImageSrc = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, 'src');
      if (originalImageSrc && originalImageSrc.set) {
        Object.defineProperty(HTMLImageElement.prototype, 'src', {
          get: originalImageSrc.get,
          set: function(value) {
            // 检查是否为地图瓦片请求
            if (typeof value === 'string' && value.includes('tile.openstreetmap.org')) {
              const hasBypassAttr = this.hasAttribute('data-bypass-offline-check');
              console.log('[图片请求] 检测到瓦片图片请求:', value.substring(0, 40) + '...',
                        '离线状态:', self.forceOfflineMode, 
                        'bypass属性:', hasBypassAttr);
              
              // 检查是否强制离线模式，并确保不是已经被标记为跳过检查的元素
              if (self.forceOfflineMode && !hasBypassAttr) {
                console.log('[网络拦截] 已阻止离线模式下的Image加载:', value.substring(0, 40) + '...');
                
                // 标记此元素为离线处理中，防止重复处理
                this.setAttribute('data-offline-processing', 'true');
                
                // 尝试从缓存加载瓦片
                const imgElement = this;
                try {
                  self.loadTileFromCache(value, imgElement)
                    .then(success => {
                      if (!success) {
                        // 缓存未命中，使用占位图像
                        console.log('[网络拦截] 离线模式下缓存未命中，使用占位图:', value.substring(0, 40) + '...');
                        originalImageSrc.set.call(imgElement, '');
                        
                        // 显示离线提示信息（如果尚未显示）
                        if (!self.hasShownOfflineMissingTilesWarning) {
                          self.hasShownOfflineMissingTilesWarning = true;
                          self.showMessage('部分瓦片在缓存中未找到，灰色区域表示未缓存的瓦片', 'warning');
                        }
                      }
                      // 缓存命中的情况下，loadTileFromCache已经设置了图像源
                      
                      // 标记图像已加载完成，这样Leaflet能够正确处理瓦片
                      imgElement.dispatchEvent(new Event('load'));
                    })
                    .catch(error => {
                      console.error('[网络拦截] 从缓存加载瓦片出错:', error);
                      // 出错时使用占位图
                      originalImageSrc.set.call(imgElement, '');
                      imgElement.dispatchEvent(new Event('load'));
                    });
                } catch (e) {
                  console.error('[网络拦截] 处理离线图像加载出错:', e);
                  // 出错时使用占位图
                  originalImageSrc.set.call(this, '');
                  this.dispatchEvent(new Event('load'));
                }
                
                // 返回，不继续默认行为
                return;
              } else {
                // 正常在线模式下的瓦片请求或被标记为跳过离线检查的元素
                console.log('[网络拦截] 在线模式下加载瓦片或带有bypass属性:', value.substring(0, 40) + '...');
                
                // 在在线模式下，添加图片加载完成后的缓存处理
                if (!hasBypassAttr) {
                  const imgElement = this;
                  this.addEventListener('load', function() {
                    console.log('[自动缓存] 在线加载的瓦片图片已加载完成，准备添加到缓存:', value.substring(0, 40) + '...');
                    self.cacheTileFromUrl(value, imgElement);
                  }, { once: true });
                }
              }
            }
            
            // 其他情况或在线模式下的请求，正常设置src
            return originalImageSrc.set.call(this, value);
          }
        });
      }
      
      console.log('[网络拦截] 网络请求拦截设置完成');
    },
    
    // 设置瓦片拦截器
    setupTileInterceptor(tileLayer, map) {
      const self = this; // 保存Vue组件实例
      
      console.log('[瓦片拦截] 开始设置瓦片拦截器');
      
      const originalCreateTile = tileLayer._createTile;
      
      tileLayer._createTile = function(coords, done) {
        console.log('[瓦片创建] 创建瓦片，坐标:', coords);
        console.log('[强制调试] Vue组件离线状态:', self.forceOfflineMode);
        console.log('[强制调试] 当前上下文:', this === tileLayer ? 'tileLayer' : '其他');
        
        const tile = originalCreateTile.call(this, coords, function() {});
        
        const url = this.getTileUrl(coords);
        // 确保每个瓦片都有这个属性，用于绕过离线拦截
        tile.setAttribute('data-bypass-offline-check', 'true');
        console.log('[瓦片创建] 设置了data-bypass-offline-check属性，避免被拦截器阻止');
        
        // 这里使用self而不是this来引用Vue组件
        self.processTileLoading(tile, url, done, this);
        
        return tile;
      };
    },
    
    // 处理瓦片加载 - 打印更详细的日志
    async processTileLoading(tile, url, done, tileLayer) {
      const shortUrl = url.substring(0, 40) + '...';
      console.log('[瓦片处理] 开始处理瓦片加载:', shortUrl);
      console.log('[强制调试] 当前执行环境检查 - forceOfflineMode:', this.forceOfflineMode);
      
      try {
        // 显式检查IndexedDB可用性
        console.log('[强制调试] 检查IndexedDB可用性');
        const testDb = await localforage.createInstance({
          name: 'leaflet-offline',
          storeName: 'tiles'
        });
        const count = await testDb.length();
        console.log('[强制调试] IndexedDB可访问，包含项目数:', count);
        
        // 检查是否在离线模式
        const isOfflineMode = this.forceOfflineMode || !navigator.onLine;
        console.log('[强制调试] 处理瓦片时的模式状态:', 
                    '离线模式:', isOfflineMode, 
                    '强制离线:', this.forceOfflineMode, 
                    '浏览器网络状态:', navigator.onLine);
        
        // 离线模式或强制使用缓存模式
        if (isOfflineMode) {
          console.log('[瓦片处理] 离线模式加载瓦片:', shortUrl);
          
          // 尝试从缓存加载
          console.log('[瓦片处理] 尝试从缓存加载瓦片:', shortUrl);
          const success = await this.loadTileFromCache(url, tile);
          
          // 如果缓存加载失败，显示占位图
          if (!success) {
            console.log('[瓦片处理] 离线模式下缓存未命中，使用占位图:', shortUrl);
            this.setPlaceholderImage(tile);
            // 显示在控制面板上的提示，只在未显示过时显示
            if (!this.hasShownOfflineMissingTilesWarning) {
              this.hasShownOfflineMissingTilesWarning = true;
              this.showMessage('部分瓦片在缓存中未找到，灰色区域表示未缓存的瓦片', 'warning');
            }
          } else {
            console.log('[瓦片处理] 离线模式成功加载缓存瓦片:', shortUrl);
          }
          
          // 设置已加载属性以让Leaflet知道瓦片已准备好
          tile.complete = true;
          
          // 告诉Leaflet瓦片已加载完成
          if (tileLayer._tileLoaded) {
            console.log('[瓦片处理] 通知Leaflet瓦片已加载完成:', shortUrl);
            tileLayer._tileLoaded(tile, true);
          }
          
          // 调用完成回调
          console.log('[瓦片处理] 调用完成回调:', shortUrl);
          done(null, tile);
          return;
        }
        
        // 在线模式 - 先检查缓存
        console.log('[瓦片处理] 在线模式，先检查缓存:', shortUrl);
        const cacheSuccess = await this.loadTileFromCache(url, tile);
        
        if (cacheSuccess) {
          // 缓存命中，直接使用缓存数据
          console.log('[瓦片处理] 在线模式使用缓存:', shortUrl);
          
          // 设置已加载属性
          tile.complete = true;
          
          // 告诉Leaflet瓦片已加载完成
          if (tileLayer._tileLoaded) {
            console.log('[瓦片处理] 通知Leaflet瓦片已加载完成:', shortUrl);
            tileLayer._tileLoaded(tile, true);
          }
          
          // 调用完成回调
          console.log('[瓦片处理] 调用完成回调:', shortUrl);
          done(null, tile);
          return;
        }
        
        // 缓存未命中，尝试在线加载
        console.log('[瓦片处理] 缓存未命中，尝试在线加载:', shortUrl);
        
        // 设置加载事件处理器
        tile.onload = () => {
          // 图像加载成功
          console.log('[瓦片处理] 在线加载成功:', shortUrl);
          
          // 缓存瓦片数据
          this.cacheTileFromUrl(url, tile);
          
          // 告诉Leaflet瓦片已加载完成
          if (tileLayer._tileLoaded) {
            console.log('[瓦片处理] 通知Leaflet瓦片已加载完成:', shortUrl);
            tileLayer._tileLoaded(tile, true);
          }
          
          // 调用完成回调
          console.log('[瓦片处理] 调用完成回调:', shortUrl);
          done(null, tile);
        };
        
        tile.onerror = (e) => {
          // 加载失败
          console.error('[瓦片处理] 在线加载失败:', shortUrl, e);
          
          // 使用占位图像
          this.setPlaceholderImage(tile);
          
          // 告诉Leaflet瓦片加载失败
          if (tileLayer._tileLoaded) {
            console.log('[瓦片处理] 通知Leaflet瓦片加载失败:', shortUrl);
            tileLayer._tileLoaded(tile, false);
          }
          
          // 调用完成回调并传递错误
          console.log('[瓦片处理] 调用完成回调(失败):', shortUrl);
          done(e, tile);
        };
        
        // 开始加载图像
        console.log('[瓦片处理] 设置瓦片src开始在线加载:', shortUrl);
        
        // 通过clone并替换的方式避免DOM缓存和拦截问题
        const oldTile = tile;
        if (!oldTile.getAttribute('data-bypass-offline-check')) {
          oldTile.setAttribute('data-bypass-offline-check', 'true');
        }
        oldTile.src = url;
        
      } catch (error) {
        console.error('[瓦片处理] 处理瓦片时出错:', shortUrl, error);
        
        // 出错时使用占位图像
        this.setPlaceholderImage(tile);
        
        // 确保回调被调用
        done(error, tile);
      }
    },
    
    // 从缓存加载瓦片 - 添加详细调试日志
    async loadTileFromCache(url, tile) {
      console.log('[缓存加载] 开始尝试从缓存加载瓦片:', url.substring(0, 50) + '...');
      
      try {
        // 规范化URL，处理子域名差异
        const normalizedUrl = this.normalizeTileUrl(url);
        if (normalizedUrl !== url) {
          console.log('[缓存加载] 规范化URL:', url.substring(0, 50) + '... => ' + normalizedUrl.substring(0, 50) + '...');
        }
        
        // 提取URL中的坐标信息，用于诊断
        let zxy = url.match(/\/(\d+)\/(\d+)\/(\d+)\.png$/);
        let coords = zxy ? `z=${zxy[1]}, x=${zxy[2]}, y=${zxy[3]}` : '未识别';
        console.log('[缓存诊断] 瓦片坐标:', coords);
        
        // 创建数据库引用
        const tileDb = await localforage.createInstance({
          name: 'leaflet-offline',
          storeName: 'tiles'
        });
        
        // 获取缓存数据 - 先尝试原始URL，再尝试规范化URL
        console.log('[缓存加载] 查询IndexedDB中的瓦片:', url.substring(0, 50) + '...');
        let cachedTile = await tileDb.getItem(url);
        
        // 如果没找到，尝试使用规范化URL
        if (!cachedTile && normalizedUrl !== url) {
          console.log('[缓存加载] 尝试使用规范化URL查询:', normalizedUrl.substring(0, 50) + '...');
          cachedTile = await tileDb.getItem(normalizedUrl);
        }
        
        // 检查缓存状态
        if (!cachedTile) {
          console.log('[缓存加载] 缓存中没有找到瓦片:', url);
          
          // 如果未找到，记录到未命中列表，用于诊断
          if (!this.cacheMisses) {
            this.cacheMisses = [];
          }
          // 限制记录数量，避免内存泄漏
          if (this.cacheMisses.length < 50) {
            this.cacheMisses.push({ url, normalizedUrl, coords, time: new Date().toISOString() });
          }
          
          return false;
        }
        
        console.log('[缓存加载] 缓存命中，数据类型:', typeof cachedTile, 
                    '包含data字段:', cachedTile.hasOwnProperty('data'),
                    '数据长度:', cachedTile.data ? cachedTile.data.length : 0);
        
        if (cachedTile && cachedTile.data && 
            typeof cachedTile.data === 'string' && 
            cachedTile.data.startsWith('data:image/')) {
          
          console.log('[缓存加载] 缓存数据格式正确，开始加载Base64图像');
          
          // 设置属性以跟踪缓存状态
          tile.setAttribute('data-from-cache', 'true');
          
          // 创建新的图像对象加载缓存的Base64数据
          const img = new Image();
          
          // 返回Promise以等待图像加载
          return new Promise((resolve) => {
            img.onload = () => {
              // 图像成功加载，将其复制到原始瓦片
              console.log('[缓存加载] Base64图像加载成功，设置到瓦片');
              tile.src = cachedTile.data;
              resolve(true);
            };
            
            img.onerror = () => {
              // 图像加载失败
              console.error('[缓存加载] Base64图像加载失败，数据可能损坏:', 
                           cachedTile.data.substring(0, 100) + '...');
              // 尝试修复或删除损坏的缓存项
              this.markCorruptCacheItem(url);
              resolve(false);
            };
            
            // 开始加载缓存的Base64数据
            console.log('[缓存加载] 尝试加载Base64图像数据，长度:', cachedTile.data.length);
            img.src = cachedTile.data;
          });
        } else {
          // 缓存数据格式无效
          if (cachedTile && cachedTile.data) {
            console.error('[缓存加载] 缓存数据格式无效:', 
                         (typeof cachedTile.data),
                         '开头:', cachedTile.data.substring(0, 50) + '...');
          } else {
            console.error('[缓存加载] 缓存数据不完整或为空');
          }
          
          // 标记为损坏的缓存
          this.markCorruptCacheItem(url);
          return false;
        }
      } catch (error) {
        console.error('[缓存加载] 从缓存加载瓦片失败:', url.substring(0, 50) + '...', error);
        return false;
      }
    },
    
    // 标记损坏的缓存项，以便后续修复
    async markCorruptCacheItem(url) {
      console.log('[缓存修复] 标记损坏的缓存项:', url.substring(0, 50) + '...');
      
      try {
        // 将损坏的URL添加到修复列表中
        if (!this.corruptCacheItems) {
          this.corruptCacheItems = [];
        }
        
        // 避免重复添加
        if (!this.corruptCacheItems.includes(url)) {
          this.corruptCacheItems.push(url);
          
          // 如果损坏项过多，触发自动修复
          if (this.corruptCacheItems.length > 10) {
            console.log('[缓存修复] 检测到多个损坏的缓存项，准备自动修复');
            // 在下一个事件循环中执行修复，避免阻塞当前操作
            setTimeout(() => {
              this.repairCorruptCache();
            }, 100);
          }
        }
      } catch (error) {
        console.error('[缓存修复] 标记损坏缓存项失败:', error);
      }
    },
    
    // 修复损坏的缓存项
    async repairCorruptCache() {
      if (!this.corruptCacheItems || this.corruptCacheItems.length === 0) {
        console.log('[缓存修复] 没有检测到损坏的缓存项');
        return;
      }
      
      console.log('[缓存修复] 开始修复损坏的缓存项，数量:', this.corruptCacheItems.length);
      
      try {
        const tileDb = await localforage.createInstance({
          name: 'leaflet-offline',
          storeName: 'tiles'
        });
        
        // 删除损坏的缓存项
        for (const url of this.corruptCacheItems) {
          console.log('[缓存修复] 删除损坏的缓存项:', url.substring(0, 50) + '...');
          await tileDb.removeItem(url);
        }
        
        // 清空修复列表
        this.corruptCacheItems = [];
        
        // 更新缓存计数
        await this.updateStoredTilesCount();
        
        console.log('[缓存修复] 已完成自动修复');
        
        // 如果当前是离线模式，提醒用户可能需要重新缓存
        if (this.forceOfflineMode) {
          this.showMessage('检测到部分缓存数据损坏，已自动修复。建议切换到在线模式重新缓存。', 'warning');
        }
      } catch (error) {
        console.error('[缓存修复] 修复损坏缓存项失败:', error);
      }
    },
    
    // 添加缓存诊断功能
    async diagnoseCacheIssues() {
      console.log('[缓存诊断] 开始诊断缓存问题');
      this.showMessage('正在诊断缓存问题...', 'info');
      
      try {
        // 获取全部瓦片
        const tileDb = await localforage.createInstance({
          name: 'leaflet-offline',
          storeName: 'tiles'
        });
        
        const keys = await tileDb.keys();
        console.log('[缓存诊断] 缓存中的瓦片总数:', keys.length);
        
        if (keys.length === 0) {
          this.showMessage('诊断结果: 缓存为空，请先缓存地图数据', 'warning');
          return;
        }
        
        // 随机检查几个瓦片，验证数据完整性
        const samplesToCheck = Math.min(5, keys.length);
        let validCount = 0;
        let invalidCount = 0;
        
        // 收集缩放级别信息
        const zoomLevels = {};
        
        for (let i = 0; i < samplesToCheck; i++) {
          const key = keys[Math.floor(Math.random() * keys.length)];
          const item = await tileDb.getItem(key);
          
          // 提取缩放级别信息
          const zMatch = key.match(/\/(\d+)\/(\d+)\/(\d+)\.png$/);
          if (zMatch) {
            const zoom = zMatch[1];
            zoomLevels[zoom] = (zoomLevels[zoom] || 0) + 1;
          }
          
          console.log('[缓存诊断] 检查样本瓦片:', key.substring(0, 50) + '...');
          
          if (item && item.data && 
              typeof item.data === 'string' && 
              item.data.startsWith('data:image/')) {
            validCount++;
            console.log('[缓存诊断] 样本瓦片有效');
          } else {
            invalidCount++;
            console.log('[缓存诊断] 样本瓦片无效或损坏');
          }
        }
        
        // 分析缓存中的缩放级别分布
        let zLevelInfo = '';
        if (Object.keys(zoomLevels).length > 0) {
          zLevelInfo = '缓存中的缩放级别: ' + Object.keys(zoomLevels).join(', ');
          console.log('[缓存诊断]', zLevelInfo);
        }
        
        // 输出诊断结果
        console.log('[缓存诊断] 结果: 有效样本:', validCount, '无效样本:', invalidCount);
        
        if (invalidCount > 0) {
          this.showMessage(`诊断结果: 检测到${invalidCount}/${samplesToCheck}的瓦片样本可能已损坏，建议使用"修复损坏缓存"功能`, 'warning');
        } else {
          let message = '诊断结果: 缓存数据完好';
          if (zLevelInfo) {
            message += `, ${zLevelInfo}`;
          }
          this.showMessage(message, 'success');
        }
        
        // 检查浏览器存储限制
        if (navigator.storage && navigator.storage.estimate) {
          const estimate = await navigator.storage.estimate();
          const usedPercentage = Math.round((estimate.usage / estimate.quota) * 100);
          console.log('[缓存诊断] 存储使用情况:', 
                     'Used:', Math.round(estimate.usage / (1024 * 1024)), 'MB,',
                     'Quota:', Math.round(estimate.quota / (1024 * 1024)), 'MB,',
                     'Usage:', usedPercentage, '%');
          
          if (usedPercentage > 80) {
            this.showMessage(`警告: 存储空间使用率已达${usedPercentage}%，接近上限，可能影响缓存功能`, 'warning');
          }
        }
        
        // 分析当前屏幕上可见的瓦片与缓存的匹配度
        const map = this.$refs.myMap.mapObject;
        const currentZoom = map.getZoom();
        const bounds = map.getBounds();
        
        console.log('[缓存诊断] 当前地图状态:', 
                   '缩放级别:', currentZoom,
                   '边界:', 
                   '北:', bounds.getNorth().toFixed(5), 
                   '南:', bounds.getSouth().toFixed(5), 
                   '东:', bounds.getEast().toFixed(5), 
                   '西:', bounds.getWest().toFixed(5));
        
        // 检查当前缩放级别是否在缓存范围内
        if (currentZoom < this.currentCacheConfig.minZoom || 
            currentZoom > this.currentCacheConfig.maxZoom) {
          this.showMessage(`警告: 当前缩放级别(${currentZoom})不在缓存范围(${this.currentCacheConfig.minZoom}-${this.currentCacheConfig.maxZoom})内`, 'warning');
        }
        
      } catch (error) {
        console.error('[缓存诊断] 诊断失败:', error);
        this.showMessage('诊断失败: ' + error.message, 'error');
      }
    },
    
    // 设置占位图像
    setPlaceholderImage(tile) {
      // 设置一个完整格式的占位图像
      const placeholderImage = '';
      
      // 标记为占位图像
      tile.setAttribute('data-placeholder', 'true');
      
      // 设置图像源
      tile.src = placeholderImage;
      
      // 标记为已加载
      tile.setAttribute('data-loaded', 'true');
    },
    
    // 验证缩放级别范围
    validateZoomRange() {
      // 确保最小值不大于最大值
      if (this.currentCacheConfig.minZoom > this.currentCacheConfig.maxZoom) {
        this.currentCacheConfig.minZoom = this.currentCacheConfig.maxZoom;
      }
    },
    
    // 保存当前地图区域
    async saveCurrentMapArea() {
      this.downloading = true;
      this.progress = 0;
      
      try {
        console.log('[缓存区域] 开始保存当前可见区域');
        
        const map = this.$refs.myMap.mapObject;
        const bounds = map.getBounds();
        const zoom = map.getZoom();
        const minCacheZoom = this.currentCacheConfig.minZoom;
        const maxCacheZoom = this.currentCacheConfig.maxZoom;
        
        console.log('[缓存区域] 当前缩放级别:', zoom, 
                   '将缓存缩放级别范围:', minCacheZoom, '到', maxCacheZoom);
        console.log('[缓存区域] 地图边界:', 
                   '北:', bounds.getNorth().toFixed(5), 
                   '南:', bounds.getSouth().toFixed(5), 
                   '东:', bounds.getEast().toFixed(5), 
                   '西:', bounds.getWest().toFixed(5));
        
        // 计算需要下载的瓦片总数
        let totalTiles = 0;
        let downloadedTiles = 0;
        
        for (let z = minCacheZoom; z <= maxCacheZoom; z++) {
          const northEast = bounds.getNorthEast();
          const southWest = bounds.getSouthWest();
          
          const northEastPoint = map.project(northEast, z);
          const southWestPoint = map.project(southWest, z);
          
          const tileSize = 256;
          
          const startX = Math.floor(southWestPoint.x / tileSize);
          const startY = Math.floor(northEastPoint.y / tileSize);
          const endX = Math.floor(northEastPoint.x / tileSize);
          const endY = Math.floor(southWestPoint.y / tileSize);
          
          const levelTiles = (endX - startX + 1) * (endY - startY + 1);
          totalTiles += levelTiles;
          console.log('[缓存区域] 缩放级别', z, '需要缓存瓦片数:', levelTiles);
        }
        
        console.log('[缓存区域] 总计需要缓存瓦片数:', totalTiles);
        
        // 创建存储实例
        const tileDb = await localforage.createInstance({
          name: 'leaflet-offline',
          storeName: 'tiles'
        });
        
        // 开始下载瓦片
        for (let z = minCacheZoom; z <= maxCacheZoom; z++) {
          console.log('[缓存区域] 开始下载缩放级别', z, '的瓦片');
          
          const northEast = bounds.getNorthEast();
          const southWest = bounds.getSouthWest();
          
          const northEastPoint = map.project(northEast, z);
          const southWestPoint = map.project(southWest, z);
          
          const tileSize = 256;
          
          const startX = Math.floor(southWestPoint.x / tileSize);
          const startY = Math.floor(northEastPoint.y / tileSize);
          const endX = Math.floor(northEastPoint.x / tileSize);
          const endY = Math.floor(southWestPoint.y / tileSize);
          
          console.log('[缓存区域] 缩放级别', z, '瓦片范围:', 
                     'X', startX, '-', endX, 
                     'Y', startY, '-', endY);
          
          for (let x = startX; x <= endX; x++) {
            for (let y = startY; y <= endY; y++) {
              const url = this.getTileUrl(x, y, z);
              await this.downloadAndStoreTile(url, tileDb);
              
              downloadedTiles++;
              this.progress = Math.floor((downloadedTiles / totalTiles) * 100);
              
              if (downloadedTiles % 10 === 0) {
                console.log('[缓存区域] 进度:', `${downloadedTiles}/${totalTiles}`, 
                           '完成', this.progress + '%');
              }
            }
          }
          
          console.log('[缓存区域] 缩放级别', z, '的瓦片下载完成');
        }
        
        // 完成下载
        this.downloading = false;
        await this.updateStoredTilesCount();
        
        console.log('[缓存区域] 地图瓦片下载完成，共', downloadedTiles, '个瓦片');
        this.showMessage(`已缓存 ${downloadedTiles} 个瓦片，覆盖缩放级别 ${minCacheZoom}-${maxCacheZoom}`, 'success');
      } catch (error) {
        console.error('[缓存区域] 保存地图区域失败:', error);
        this.downloading = false;
        this.showMessage('缓存地图失败: ' + error.message, 'error');
      }
    },
    
    // 获取瓦片URL
    getTileUrl(x, y, z) {
      const url = this.url
        .replace('{s}', 'a') // 固定使用一个子域名
        .replace('{z}', z)
        .replace('{x}', x)
        .replace('{y}', y);
      return url;
    },
    
    // 规范化瓦片URL，确保不同子域名的相同瓦片能匹配上
    normalizeTileUrl(url) {
      // 将所有子域名统一规范为'a'
      if (typeof url === 'string') {
        // 如果是形如 https://a.tile.openstreetmap.org/... 的URL
        return url.replace(/(https?:\/\/)[a-z](\.tile\.openstreetmap\.org)/, '$1a$2');
      }
      return url;
    },
    
    // 下载并存储瓦片
    async downloadAndStoreTile(url, db) {
      try {
        console.log('[瓦片下载] 开始下载瓦片:', url.substring(0, 40) + '...');
        
        const response = await fetch(url);
        if (!response.ok) {
          console.error('[瓦片下载] 下载失败:', response.status, response.statusText);
          throw new Error(`Failed to fetch tile: ${response.status} ${response.statusText}`);
        }
        
        console.log('[瓦片下载] 下载成功，开始处理数据');
        const blob = await response.blob();
        console.log('[瓦片下载] 获取到Blob数据，大小:', blob.size, '字节');
        
        // 转换为base64
        return new Promise((resolve, reject) => {
          const reader = new FileReader();
          reader.onload = async (e) => {
            try {
              const base64data = e.target.result;
              console.log('[瓦片下载] 已转换为Base64数据，长度:', base64data.length);
              
              // 确保base64数据格式正确
              if (typeof base64data === 'string' && base64data.startsWith('data:')) {
                console.log('[瓦片下载] Base64数据格式验证通过，保存到IndexedDB');
                await db.setItem(url, {
                  data: base64data,
                  timestamp: Date.now()
                });
                console.log('[瓦片下载] 保存成功');
                resolve();
              } else {
                console.error('[瓦片下载] Base64数据格式无效', base64data ? base64data.substring(0, 50) + '...' : 'empty');
                reject(new Error('Invalid base64 data format'));
              }
            } catch (error) {
              console.error('[瓦片下载] 保存瓦片数据出错', error);
              reject(error);
            }
          };
          reader.onerror = (error) => {
            console.error('[瓦片下载] 读取Blob为DataURL失败', error);
            reject(error);
          };
          console.log('[瓦片下载] 开始读取Blob为DataURL');
          reader.readAsDataURL(blob);
        });
      } catch (error) {
        console.error(`[瓦片下载] 下载瓦片失败 ${url}:`, error);
      }
    },
    
    // 清除缓存
    async clearCache() {
      try {
        const tileDb = await localforage.createInstance({
          name: 'leaflet-offline',
          storeName: 'tiles'
        });
        await tileDb.clear();
        this.storedTilesCount = 0;
        console.log('缓存已清除');
      } catch (error) {
        console.error('清除缓存失败:', error);
      }
    },
    
    // 保存当前可见区域（UI按钮调用）
    saveVisibleArea() {
      this.saveCurrentMapArea();
    },
    
    // 更新已存储瓦片计数
    async updateStoredTilesCount() {
      try {
        console.log('[缓存管理] 开始更新缓存计数');
        
        const tileDb = await localforage.createInstance({
          name: 'leaflet-offline',
          storeName: 'tiles'
        });
        
        const keys = await tileDb.keys();
        const previousCount = this.storedTilesCount;
        this.storedTilesCount = keys.length;
        
        console.log('[缓存管理] 存储的瓦片数量:', this.storedTilesCount, 
                   '变化:', (this.storedTilesCount - previousCount > 0 ? '+' : '') + (this.storedTilesCount - previousCount));
        
        // 估算占用空间
        if (keys.length > 0) {
          try {
            // 采样5个瓦片计算平均大小
            const sampleSize = Math.min(5, keys.length);
            let totalSize = 0;
            
            for (let i = 0; i < sampleSize; i++) {
              const key = keys[Math.floor(Math.random() * keys.length)];
              const item = await tileDb.getItem(key);
              if (item && item.data) {
                totalSize += item.data.length;
              }
            }
            
            const avgTileSize = totalSize / sampleSize;
            const estimatedTotalSize = avgTileSize * keys.length / (1024 * 1024);
            
            console.log('[缓存管理] 估计缓存占用空间:', estimatedTotalSize.toFixed(2), 'MB',
                       '平均瓦片大小:', (avgTileSize / 1024).toFixed(2), 'KB');
          } catch (e) {
            console.error('[缓存管理] 计算缓存大小出错:', e);
          }
        }
        
        console.log('[强制调试] IndexedDB状态检查');
        const testDb = await localforage.createInstance({
          name: 'leaflet-offline',
          storeName: 'tiles'
        });
        const testKeys = await testDb.keys();
        console.log('[强制调试] 数据库可访问，包含瓦片数:', testKeys.length);
      } catch (error) {
        console.error('[缓存管理] 获取瓦片计数失败:', error);
        this.storedTilesCount = 0;
      }
    },
    
    // 导出地图缓存
    async exportMapCache() {
      try {
        console.log('[缓存导出] 开始导出地图缓存');
        
        // 获取所有缓存的瓦片
        const tileDb = await localforage.createInstance({
          name: 'leaflet-offline',
          storeName: 'tiles'
        });
        
        const keys = await tileDb.keys();
        console.log('[缓存导出] 准备导出瓦片数量:', keys.length);
        
        if (keys.length === 0) {
          this.showMessage('没有可导出的缓存数据', 'warning');
          return;
        }
        
        const tiles = {};
        let processedCount = 0;
        let totalSize = 0;
        
        for (const key of keys) {
          const item = await tileDb.getItem(key);
          tiles[key] = item;
          
          processedCount++;
          if (item && item.data) {
            totalSize += item.data.length;
          }
          
          if (processedCount % 50 === 0) {
            console.log('[缓存导出] 进度:', processedCount, '/', keys.length);
          }
        }
        
        // 计算大小
        const mbSize = (totalSize / (1024 * 1024)).toFixed(2);
        console.log('[缓存导出] 生成导出数据, 大小约:', mbSize, 'MB');
        
        // 将数据转换为Blob
        const exportData = {
          tiles,
          points: this.points,
          lineCoordinates: this.lineCoordinates,
          metadata: {
            exportDate: new Date().toISOString(),
            tileCount: keys.length,
            estimatedSizeMB: mbSize
          }
        };
        
        console.log('[缓存导出] 准备创建JSON数据');
        const blob = new Blob([JSON.stringify(exportData)], {type: 'application/json'});
        console.log('[缓存导出] 创建下载链接');
        
        // 创建下载链接
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = 'gis-map-cache.json';
        document.body.appendChild(a);
        
        console.log('[缓存导出] 触发下载');
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
        
        console.log('[缓存导出] 导出完成, 文件大小:', blob.size, '字节');
        this.showMessage(`导出完成: ${keys.length}个瓦片, 文件大小约${mbSize}MB`, 'success');
      } catch (error) {
        console.error('[缓存导出] 导出地图缓存失败:', error);
        this.showMessage('导出失败: ' + error.message, 'error');
      }
    },
    
    // 导入地图缓存
    async importMapCache(file) {
      try {
        console.log('[缓存导入] 开始导入地图缓存, 文件大小:', (file.size / (1024 * 1024)).toFixed(2), 'MB');
        this.downloading = true;
        this.progress = 0;
        
        const reader = new FileReader();
        reader.onload = async (e) => {
          try {
            console.log('[缓存导入] 文件读取完成, 开始解析JSON');
            // 解析导入的JSON文件
            const data = JSON.parse(e.target.result);
            
            // 验证导入数据
            if (!data.tiles || typeof data.tiles !== 'object') {
              console.error('[缓存导入] 导入文件格式无效');
              throw new Error('导入文件格式无效，找不到瓦片数据');
            }
            
            console.log('[缓存导入] 文件解析成功，包含瓦片数:', Object.keys(data.tiles).length);
            
            if (data.metadata) {
              console.log('[缓存导入] 导入文件元数据:', 
                         '导出日期:', data.metadata.exportDate,
                         '瓦片数:', data.metadata.tileCount,
                         '预估大小:', data.metadata.estimatedSizeMB, 'MB');
            }
            
            // 初始化IndexedDB
            const tileDb = await localforage.createInstance({
              name: 'leaflet-offline',
              storeName: 'tiles'
            });
            
            // 清除现有缓存
            console.log('[缓存导入] 清除现有缓存');
            await tileDb.clear();
            
            // 计算总数
            const totalItems = Object.keys(data.tiles).length;
            let processedItems = 0;
            let successCount = 0;
            let errorCount = 0;
            
            console.log('[缓存导入] 开始保存瓦片到本地存储');
            // 保存瓦片
            for (const [key, value] of Object.entries(data.tiles)) {
              try {
                // 验证瓦片数据
                if (value && value.data && typeof value.data === 'string' && value.data.startsWith('data:image/')) {
                  await tileDb.setItem(key, value);
                  successCount++;
                } else {
                  console.error('[缓存导入] 跳过无效的瓦片数据:', key);
                  errorCount++;
                }
              } catch (tileError) {
                console.error('[缓存导入] 保存瓦片失败:', key, tileError);
                errorCount++;
              }
              
              processedItems++;
              this.progress = Math.floor((processedItems / totalItems) * 100);
              
              if (processedItems % 50 === 0 || processedItems === totalItems) {
                console.log('[缓存导入] 进度:', processedItems, '/', totalItems, 
                           '(', this.progress, '%)',
                           '成功:', successCount,
                           '失败:', errorCount);
              }
            }
            
            // 导入点和线数据
            if (data.points) {
              console.log('[缓存导入] 导入', data.points.length, '个坐标点');
              this.points = data.points;
            }
            
            if (data.lineCoordinates) {
              console.log('[缓存导入] 导入', data.lineCoordinates.length, '个线段坐标');
              this.lineCoordinates = data.lineCoordinates;
            }
            
            console.log('[缓存导入] 更新缓存计数');
            await this.updateStoredTilesCount();
            
            // 刷新地图
            this.$nextTick(() => {
              console.log('[缓存导入] 刷新地图以使用新缓存');
              // 完全重载地图瓦片层以使用新的缓存
              const map = this.$refs.myMap.mapObject;
              
              // 移除旧的图层
              if (this.tileLayer) {
                map.removeLayer(this.tileLayer);
              }
              
              // 重新初始化离线地图
              console.log('[缓存导入] 重新初始化离线地图');
              this.initOfflineMap();
              
              // 显示成功消息
              this.showMessage(`缓存导入完成: 成功${successCount}个, 失败${errorCount}个瓦片`, errorCount > 0 ? 'warning' : 'success');
              
              this.downloading = false;
              console.log('[缓存导入] 导入流程完成');
            });
          } catch (parseError) {
            console.error('[缓存导入] 解析导入文件失败:', parseError);
            this.showMessage('导入失败: ' + parseError.message, 'error');
            this.downloading = false;
          }
        };
        
        reader.onerror = (error) => {
          console.error('[缓存导入] 读取文件失败:', error);
          this.showMessage('读取文件失败', 'error');
          this.downloading = false;
        };
        
        console.log('[缓存导入] 开始读取文件');
        reader.readAsText(file);
      } catch (error) {
        console.error('[缓存导入] 导入地图缓存失败:', error);
        this.downloading = false;
        this.showMessage('导入缓存失败: ' + error.message, 'error');
      }
    },
    
    // 显示消息
    showMessage(message, type = 'success') {
      const messageElement = document.createElement('div');
      messageElement.className = 'map-message ' + type;
      messageElement.textContent = message;
      
      document.querySelector('.map-container').appendChild(messageElement);
      
      // 3秒后自动消失
      setTimeout(() => {
        if (messageElement.parentNode) {
          messageElement.parentNode.removeChild(messageElement);
        }
      }, 3000);
    },
    
    // 处理文件上传
    handleFileUpload(event) {
      const file = event.target.files[0];
      if (file) {
        this.importMapCache(file);
      }
    },
    
    // 切换离线模式
    toggleOfflineMode() {
      this.forceOfflineMode = !this.forceOfflineMode;
      
      // 保存用户选择到本地存储
      localStorage.setItem('gisMapOfflineMode', this.forceOfflineMode ? 'true' : 'false');
      
      // 清除缓存的请求结果
      if (window.caches) {
        caches.keys().then(cacheNames => {
          return Promise.all(
            cacheNames.map(cacheName => {
              if (cacheName.includes('tile')) {
                return caches.delete(cacheName);
              }
            })
          );
        });
      }
      
      // 提示用户
      this.showMessage(this.forceOfflineMode ? '已切换到离线模式' : '已切换到在线模式', 'info');
      
      // 延迟执行，确保状态已更新
      setTimeout(() => {
        // 完全重新创建地图瓦片层，以确保正确应用离线模式
        this.recreateMapLayers();
      }, 100);
    },
    
    // 完全重新创建地图图层
    recreateMapLayers() {
      try {
        const map = this.$refs.myMap.mapObject;
        
        // 移除所有现有图层
        map.eachLayer(layer => {
          if (layer instanceof L.TileLayer) {
            map.removeLayer(layer);
          }
        });
        
        // 重新初始化离线地图
        this.initOfflineMap();
        
        // 强制刷新已加载的瓦片
        if (this.tileLayer) {
          this.tileLayer.redraw();
        }
        
        console.log('地图图层已重新创建，模式:', this.forceOfflineMode ? '离线' : '在线');
      } catch (error) {
        console.error('重新创建地图图层失败:', error);
      }
    },
    
    // 刷新地图 - 简化版本，改为调用完整的重建
    refreshMap() {
      this.recreateMapLayers();
    },
    
    // 更新网络状态
    updateNetworkStatus() {
      const previousState = this.isOnline;
      this.isOnline = navigator.onLine;
      
      if (previousState !== this.isOnline) {
        console.log(this.isOnline ? '网络已连接' : '网络已断开，使用缓存模式');
        
        // 仅当不是强制离线模式时，网络状态变化才触发刷新
        if (!this.forceOfflineMode) {
          this.refreshMap();
        }
        
        // 显示网络状态变化消息
        if (this.isOnline) {
          this.showMessage('网络已连接', 'info');
        } else {
          this.showMessage('网络已断开，使用缓存模式', 'warning');
        }
      }
    },
    
    // 主动检测网络状态
    checkNetworkConnection() {
      // 通过尝试加载一个小图片来检测网络连接
      return new Promise((resolve) => {
        const testImage = new Image();
        testImage.onload = () => {
          this.isOnline = true;
          resolve(true);
        };
        testImage.onerror = () => {
          this.isOnline = false;
          resolve(false);
        };
        
        // 添加时间戳防止缓存
        testImage.src = 'https://www.openstreetmap.org/favicon.ico?' + Date.now();
        
        // 设置3秒超时
        setTimeout(() => {
          if (!this.isOnline) {
            resolve(false);
          }
        }, 3000);
      });
    },
    
    // 重置并修复缓存
    async repairCache() {
      try {
        this.downloading = true;
        this.progress = 0;
        this.showMessage('正在尝试修复缓存...', 'info');
        
        // 重新创建存储实例
        const oldDb = await localforage.createInstance({
          name: 'leaflet-offline',
          storeName: 'tiles'
        });
        
        // 获取所有现有的瓦片数据
        const keys = await oldDb.keys();
        const totalItems = keys.length;
        
        if (totalItems === 0) {
          this.showMessage('没有发现缓存数据，请先导入缓存', 'warning');
          this.downloading = false;
          return;
        }
        
        // 创建临时存储
        const tempDb = await localforage.createInstance({
          name: 'leaflet-offline-temp',
          storeName: 'tiles'
        });
        
        // 清除临时存储
        await tempDb.clear();
        
        let processedItems = 0;
        let validCount = 0;
        let invalidCount = 0;
        
        // 检查并修复所有瓦片数据
        for (const key of keys) {
          try {
            const item = await oldDb.getItem(key);
            
            // 验证瓦片数据格式
            if (item && item.data && typeof item.data === 'string' && item.data.startsWith('data:image/')) {
              // 有效的瓦片数据，保存到临时存储
              await tempDb.setItem(key, item);
              validCount++;
            } else {
              console.error('发现无效的瓦片数据:', key);
              invalidCount++;
            }
          } catch (error) {
            console.error('处理瓦片时出错:', key, error);
            invalidCount++;
          }
          
          processedItems++;
          this.progress = Math.floor((processedItems / totalItems) * 100);
        }
        
        // 清除原始存储
        await oldDb.clear();
        
        // 将临时存储中的数据复制回原始存储
        const tempKeys = await tempDb.keys();
        processedItems = 0;
        
        for (const key of tempKeys) {
          const item = await tempDb.getItem(key);
          await oldDb.setItem(key, item);
          
          processedItems++;
          this.progress = 50 + Math.floor((processedItems / tempKeys.length) * 50);
        }
        
        // 清除临时存储
        await tempDb.clear();
        
        // 更新计数并刷新地图
        await this.updateStoredTilesCount();
        
        this.showMessage(`缓存修复完成: 有效${validCount}个, 无效${invalidCount}个瓦片`, 
                        invalidCount > 0 ? 'warning' : 'success');
        
        // 刷新地图
        this.$nextTick(() => {
          if (this.$refs.myMap && this.$refs.myMap.mapObject) {
            const map = this.$refs.myMap.mapObject;
            
            // 移除旧的图层
            if (this.tileLayer) {
              map.removeLayer(this.tileLayer);
            }
            
            // 重新初始化离线地图
            this.initOfflineMap();
          }
          
          this.downloading = false;
        });
        
      } catch (error) {
        console.error('修复缓存失败:', error);
        this.showMessage('修复缓存失败: ' + error.message, 'error');
        this.downloading = false;
      }
    },
    
    // 设置自定义缓存功能
    setupCustomCaching(map, tileLayer) {
      // 创建自定义控制按钮
      const cacheControl = L.control({position: 'topright'});
      cacheControl.onAdd = (map) => {
        const div = L.DomUtil.create('div', 'leaflet-control leaflet-control-custom');
        div.innerHTML = '<button class="leaflet-control-button save-area" title="保存当前区域">💾</button>' +
                        '<button class="leaflet-control-button clear-cache" title="清除缓存">🗑️</button>';
        
        L.DomEvent.on(div.querySelector('.save-area'), 'click', (e) => {
          L.DomEvent.stopPropagation(e);
          this.saveCurrentMapArea();
        });
        
        L.DomEvent.on(div.querySelector('.clear-cache'), 'click', (e) => {
          L.DomEvent.stopPropagation(e);
          this.clearCache();
        });
        
        return div;
      };
      
      // 添加到地图
      cacheControl.addTo(map);
      
      // 初始化缓存计数
      this.updateStoredTilesCount();
    },
    
    // 从URL加载瓦片并缓存
    async cacheTileFromUrl(url, tile) {
      // 如果是强制离线模式，跳过缓存处理
      if (this.forceOfflineMode) {
        console.log('[瓦片缓存] 强制离线模式下不执行自动缓存');
        return;
      }
      
      try {
        console.log('[瓦片缓存] 开始缓存瓦片:', url.substring(0, 40) + '...');
        
        // 使用fetch API直接获取瓦片，避免Canvas跨域安全问题
        console.log('[瓦片缓存] 使用fetch直接获取瓦片数据');
        const response = await fetch(url, {
          method: 'GET',
          credentials: 'omit', // 不发送凭证
          mode: 'cors',  // 尝试CORS请求
          cache: 'no-store' // 不使用缓存，总是请求新的
        });
        
        if (!response.ok) {
          throw new Error(`获取瓦片失败: ${response.status} ${response.statusText}`);
        }
        
        // 获取图像数据
        const blob = await response.blob();
        
        // 将blob转换为base64
        const reader = new FileReader();
        reader.readAsDataURL(blob);
        
        // 等待读取完成
        const base64data = await new Promise((resolve, reject) => {
          reader.onload = () => resolve(reader.result);
          reader.onerror = () => reject(new Error('转换blob为base64失败'));
        });
        
        console.log('[瓦片缓存] 已获取并转换为Base64数据，长度:', base64data.length);
          
          // 保存到缓存
          const tileDb = await localforage.createInstance({
            name: 'leaflet-offline',
            storeName: 'tiles'
          });
          
          console.log('[瓦片缓存] 正在保存到IndexedDB...');
          await tileDb.setItem(url, {
            data: base64data,
            timestamp: Date.now()
          });
          console.log('[瓦片缓存] 已成功保存到IndexedDB');
          
          // 更新计数
          this.updateStoredTilesCount();
        
        // 显示一次提示（设置标志位避免多次显示）
        if (!this.hasShownAutoCacheMessage) {
          this.hasShownAutoCacheMessage = true;
          this.showMessage('已开始自动缓存浏览的地图瓦片', 'info');
        }
      } catch (error) {
        console.error('[瓦片缓存] 缓存在线瓦片失败:', url.substring(0, 40) + '...', error);
      }
    },
    
    // 从URL加载瓦片并缓存
    async loadTileFromCacheForFetch(url) {
      try {
        console.log('[缓存加载] 开始尝试从缓存加载瓦片:', url.substring(0, 50) + '...');
        
        // 规范化URL，处理子域名差异
        const normalizedUrl = this.normalizeTileUrl(url);
        if (normalizedUrl !== url) {
          console.log('[缓存加载] 规范化URL:', url.substring(0, 50) + '... => ' + normalizedUrl.substring(0, 50) + '...');
        }
        
        // 创建数据库引用
        const tileDb = await localforage.createInstance({
          name: 'leaflet-offline',
          storeName: 'tiles'
        });
        
        // 获取缓存数据 - 先尝试原始URL，再尝试规范化URL
        console.log('[缓存加载] 查询IndexedDB中的瓦片:', url.substring(0, 50) + '...');
        let cachedTile = await tileDb.getItem(url);
        
        // 如果没找到，尝试使用规范化URL
        if (!cachedTile && normalizedUrl !== url) {
          console.log('[缓存加载] 尝试使用规范化URL查询:', normalizedUrl.substring(0, 50) + '...');
          cachedTile = await tileDb.getItem(normalizedUrl);
        }
        
        // 检查缓存状态
        if (!cachedTile) {
          console.log('[缓存加载] 缓存中没有找到瓦片:', url.substring(0, 50) + '...');
          return null;
        }
        
        console.log('[缓存加载] 缓存命中，数据类型:', typeof cachedTile, 
                    '包含data字段:', cachedTile.hasOwnProperty('data'),
                    '数据长度:', cachedTile.data ? cachedTile.data.length : 0);
        
        if (cachedTile && cachedTile.data && 
            typeof cachedTile.data === 'string' && 
            cachedTile.data.startsWith('data:image/')) {
          
          console.log('[缓存加载] 缓存数据格式正确，开始加载Base64图像');
          
          // cachedTile是普通对象，不是DOM元素，无需设置属性
          // 移除: cachedTile.setAttribute('data-from-cache', 'true');
          
          // 创建新的图像对象加载缓存的Base64数据
          const img = new Image();
          
          // 返回Promise以等待图像加载
          return new Promise((resolve) => {
            img.onload = () => {
              // 图像成功加载
              console.log('[缓存加载] Base64图像加载成功');
              resolve({
                data: cachedTile.data,
                timestamp: Date.now()
              });
            };
            
            img.onerror = () => {
              // 图像加载失败
              console.error('[缓存加载] Base64图像加载失败，数据可能损坏:', 
                           cachedTile.data.substring(0, 100) + '...');
              // 尝试修复或删除损坏的缓存项
              this.markCorruptCacheItem(url);
              resolve(null);
            };
            
            // 开始加载缓存的Base64数据
            console.log('[缓存加载] 尝试加载Base64图像数据，长度:', cachedTile.data.length);
            img.src = cachedTile.data;
          });
        } else {
          // 缓存数据格式无效
          if (cachedTile && cachedTile.data) {
            console.error('[缓存加载] 缓存数据格式无效:', 
                         (typeof cachedTile.data),
                         '开头:', cachedTile.data.substring(0, 50) + '...');
          } else {
            console.error('[缓存加载] 缓存数据不完整或为空');
          }
          
          // 标记为损坏的缓存
          this.markCorruptCacheItem(url);
          return null;
        }
      } catch (error) {
        console.error('[缓存加载] 从缓存加载瓦片失败:', url.substring(0, 50) + '...', error);
        return null;
      }
    },
    
    // 添加诊断缓存未命中的功能
    showCacheMisses() {
      console.log('[缓存诊断] 开始分析未命中缓存模式');
      
      if (!this.cacheMisses || this.cacheMisses.length === 0) {
        this.showMessage('暂未发现缓存未命中记录', 'info');
        return;
      }
      
      // 显示缓存未命中数量
      console.log(`[缓存诊断] 发现 ${this.cacheMisses.length} 个缓存未命中`);
      
      // 分析缩放级别
      const zoomLevels = {};
      this.cacheMisses.forEach(miss => {
        const match = miss.coords.match(/z=(\d+)/);
        if (match) {
          const zoom = match[1];
          zoomLevels[zoom] = (zoomLevels[zoom] || 0) + 1;
        }
      });
      
      console.log('[缓存诊断] 缩放级别分布:');
      for (const [zoom, count] of Object.entries(zoomLevels)) {
        console.log(`- 缩放级别 ${zoom}: ${count} 个未命中`);
      }
      
      // 提取前5个未命中的URL进行分析
      console.log('[缓存诊断] 未命中URL示例:');
      this.cacheMisses.slice(0, 5).forEach((miss, index) => {
        console.log(`${index + 1}. URL: ${miss.url}`);
        console.log(`   坐标: ${miss.coords}`);
        console.log(`   时间: ${miss.time}`);
      });
      
      // 根据分析结果给出建议
      let message = `发现${this.cacheMisses.length}个缓存未命中`;
      let hasZoomIssue = false;
      
      // 检查是否有当前缓存配置范围外的缩放级别
      for (const zoom of Object.keys(zoomLevels)) {
        if (parseInt(zoom) < this.currentCacheConfig.minZoom || 
            parseInt(zoom) > this.currentCacheConfig.maxZoom) {
          hasZoomIssue = true;
          message += `，包括缓存范围外的缩放级别: ${zoom}`;
        }
      }
      
      if (hasZoomIssue) {
        message += '。建议调整缓存缩放级别范围并重新缓存。';
        this.showMessage(message, 'warning');
      } else {
        message += '。建议重新保存当前可见区域。';
        this.showMessage(message, 'info');
      }
      
      // 提供一个诊断提示框
      const diagDiv = document.createElement('div');
      diagDiv.className = 'cache-diagnosis';
      diagDiv.innerHTML = `
        <h3>缓存未命中分析</h3>
        <p>发现 ${this.cacheMisses.length} 个缓存未命中</p>
        <h4>缩放级别分布:</h4>
        <ul>
          ${Object.entries(zoomLevels).map(([zoom, count]) => {
            const isOutOfRange = parseInt(zoom) < this.currentCacheConfig.minZoom || 
                                 parseInt(zoom) > this.currentCacheConfig.maxZoom;
            return `<li>缩放级别 ${zoom}: ${count} 个 (${isOutOfRange ? '<span style="color:red">超出缓存范围</span>' : '在缓存范围内'})</li>`;
          }).join('')}
        </ul>
        <p>当前缓存配置范围: ${this.currentCacheConfig.minZoom} - ${this.currentCacheConfig.maxZoom}</p>
        <button class="close-btn">关闭</button>
      `;
      
      document.querySelector('.map-container').appendChild(diagDiv);
      
      // 关闭按钮事件
      diagDiv.querySelector('.close-btn').addEventListener('click', () => {
        if (diagDiv.parentNode) {
          diagDiv.parentNode.removeChild(diagDiv);
        }
      });
    },
    // 添加获取并打印当前缩放级别的方法
    // 显示当前缩放级别
    showCurrentZoom() {
      const map = this.$refs.myMap.mapObject;
      const currentZoom = map.getZoom();
      this.currentDisplayZoom = currentZoom;
      console.log('[地图] 当前缩放级别 (方法调用):', currentZoom);
      this.showMessage(`当前地图缩放级别: ${currentZoom}`, 'info');
      
      // 检查当前缩放级别是否在缓存配置范围内
      if (currentZoom < this.currentCacheConfig.minZoom || 
          currentZoom > this.currentCacheConfig.maxZoom) {
        this.showMessage(`警告: 当前缩放级别(${currentZoom})不在缓存范围(${this.currentCacheConfig.minZoom}-${this.currentCacheConfig.maxZoom})内`, 'warning');
      }
    },
    
    // 切换缓存控制面板显示/隐藏
    toggleCachePanel() {
      this.showCachePanel = !this.showCachePanel;
    },
    
    // 设置自定义瓦片占位图
    setPlaceholderImage(tile) {
      // 使用灰色网格图像作为占位图
      tile.src = '';
    },
    
    // 创建塔杆图标
    createTowerIcon() {
      // 创建塔杆图标的SVG字符串
      const towerSvg = `
        <svg xmlns="http://www.w3.org/2000/svg" width="20" height="30" viewBox="0 0 20 30">
          <rect x="8" y="0" width="4" height="30" fill="#333"/>
          <rect x="4" y="5" width="12" height="2" fill="#333"/>
          <rect x="4" y="15" width="12" height="2" fill="#333"/>
          <rect x="4" y="25" width="12" height="2" fill="#333"/>
        </svg>
      `;
      
      // 使用SVG创建divIcon
      this.towerIcon = L.divIcon({
        html: towerSvg,
        className: 'tower-icon-container',
        iconSize: [20, 30],
        iconAnchor: [10, 30],
        popupAnchor: [0, -30]
      });
      
      console.log('[地图] 已创建塔杆图标');
    },
    
    // 确保所选的缩放级别最小值不大于最大值
    validateZoomRange() {
      // 确保最小值不大于最大值
      if (this.currentCacheConfig.minZoom > this.currentCacheConfig.maxZoom) {
        this.currentCacheConfig.minZoom = this.currentCacheConfig.maxZoom;
      }
    },
    
    /**
     * 渲染线路到地图上
     * @param {Object} options - 配置选项
     * @param {Array} options.originalRoute - 原有线路坐标数组 [[lat, lng], [lat, lng], ...]
     * @param {Array} [options.detourRoutes] - 迂回线路坐标数组的数组 [[[lat, lng], ...], [[lat, lng], ...]]
     * @param {Object} [options.originalRouteConfig] - 原有线路配置
     * @param {Object} [options.detourRouteConfig] - 迂回线路配置
     * @returns {Array} - 添加到地图上的线路对象数组
     */
    renderRoutes(options) {
      const routes = [];
      
      // 默认配置
      const defaultOriginalConfig = {
        color: '#FF0000',
        weight: 3,
        dashArray: '5, 10',
        opacity: 0.8,
        name: '原有线路',
        description: '原有线路'
      };
      
      const defaultDetourConfig = {
        color: '#0000FF',
        weight: 3,
        dashArray: '10, 5',
        opacity: 0.8,
        name: '迂回线路',
        description: '迂回线路'
      };
      
      // 合并配置
      const originalConfig = { ...defaultOriginalConfig, ...options.originalRouteConfig };
      const detourConfig = { ...defaultDetourConfig, ...options.detourRouteConfig };
      
      // 添加原有线路
      if (options.originalRoute && options.originalRoute.length > 0) {
        // 创建塔杆名称数组，如果未提供，则生成默认值
        const towerNames = originalConfig.towerNames || options.originalRoute.map((_, index) => {
          if (index === 0) {
            return '1号塔';
          } else if (index === options.originalRoute.length - 1) {
            return `${options.originalRoute.length}号塔`;
          } else {
            return `${index + 1}号塔`;
          }
        });
        
        routes.push({
          coordinates: options.originalRoute,
          color: originalConfig.color,
          weight: originalConfig.weight,
          dashArray: originalConfig.dashArray,
          opacity: originalConfig.opacity,
          name: originalConfig.name,
          description: originalConfig.description,
          towerNames: towerNames
        });
      }
      
      // 添加迂回线路
      if (options.detourRoutes && options.detourRoutes.length > 0) {
        options.detourRoutes.forEach((route, index) => {
          // 如果提供了迂回线路配置数组，使用对应的配置
          const routeConfig = options.detourRoutesConfig && options.detourRoutesConfig[index] 
            ? { ...detourConfig, ...options.detourRoutesConfig[index] }
            : { ...detourConfig };
          
          // 创建塔杆名称数组，如果未提供，则生成默认值
          const towerNames = routeConfig.towerNames || route.map((_, idx) => {
            if (idx === 0) {
              return '起始塔';
            } else if (idx === route.length - 1) {
              return '终止塔';
            } else {
              return `塔杆${idx + 1}`;
            }
          });
          
          // 如果未提供名称，添加编号
          if (routeConfig.name === defaultDetourConfig.name) {
            routeConfig.name += ` ${index + 1}`;
          }
          
          routes.push({
            coordinates: route,
            color: routeConfig.color,
            weight: routeConfig.weight,
            dashArray: routeConfig.dashArray,
            opacity: routeConfig.opacity,
            name: routeConfig.name,
            description: routeConfig.description,
            towerNames: towerNames
          });
        });
      }
      
      // 将线路添加到组件的数据中
      this.routes = routes;
      
      // 如果地图已加载，添加箭头装饰器
      this.$nextTick(() => {
        // this.addRouteArrowsToRoutes();
      });
      
      return routes;
    },
    
    // 为所有线路添加箭头装饰器
    addRouteArrowsToRoutes() {
      console.log('[线路箭头] 尝试为所有线路添加箭头装饰器');
      
      // 确保地图和L.polylineDecorator可用
      if (!this.$refs.myMap || !this.$refs.myMap.mapObject) {
        console.error('[线路箭头] 无法添加箭头装饰器，地图组件未加载');
        return;
      }
      
      // 检查polylineDecorator插件是否可用
      if (!L.polylineDecorator) {
        console.error('[线路箭头] L.polylineDecorator未定义，请确保已正确加载插件');
        return;
      }
      
      const map = this.$refs.myMap.mapObject;
      
      // 移除现有的装饰器
      if (this.routeDecorators) {
        this.routeDecorators.forEach(decorator => {
          map.removeLayer(decorator);
        });
      }
      
      this.routeDecorators = [];
      
      // 为每条线路添加装饰器
      this.routes.forEach((route, index) => {
        const decorator = L.polylineDecorator(route.coordinates, {
          patterns: [
            {
              offset: '25%',
              repeat: 50,
              symbol: L.Symbol.arrowHead({
                pixelSize: 15,
                headAngle: 60,
                pathOptions: {
                  fillOpacity: 0.9,
                  weight: 0,
                  color: route.color
                }
              })
            }
          ]
        }).addTo(map);
        
        this.routeDecorators.push(decorator);
      });
      
      console.log('[线路箭头] 已添加线路箭头装饰器');
    },
    
    // 为线路添加箭头装饰器 (原有方法，保留但不再使用)
    addRouteArrows() {
      console.log('[线路箭头] 尝试添加线路箭头装饰器');
      
      // 确保地图和L.polylineDecorator可用
      if (!this.$refs.myMap || !this.$refs.myMap.mapObject) {
        console.error('[线路箭头] 无法添加箭头装饰器，地图组件未加载');
        return;
      }
      
      // 检查polylineDecorator插件是否可用
      if (!L.polylineDecorator) {
        console.error('[线路箭头] L.polylineDecorator未定义，请确保已正确加载插件');
        return;
      }
      
      const map = this.$refs.myMap.mapObject;
      
      // 为原有线路添加红色箭头
      const originalRouteDecorator = L.polylineDecorator(this.originalRouteCoordinates, {
        patterns: [
          {
            offset: '25%',
            repeat: 50,
            symbol: L.Symbol.arrowHead({
              pixelSize: 15,
              headAngle: 60,
              pathOptions: {
                fillOpacity: 0.9,
                weight: 0,
                color: '#FF0000'
              }
            })
          }
        ]
      }).addTo(map);
      
      // 为应急迂回线路1添加蓝色箭头
      const emergencyRoute1Decorator = L.polylineDecorator(this.emergencyRoute1Coordinates, {
        patterns: [
          {
            offset: '25%',
            repeat: 50,
            symbol: L.Symbol.arrowHead({
              pixelSize: 15,
              headAngle: 60,
              pathOptions: {
                fillOpacity: 0.9,
                weight: 0,
                color: '#0000FF'
              }
            })
          }
        ]
      }).addTo(map);
      
      // 为应急迂回线路2添加蓝色箭头
      const emergencyRoute2Decorator = L.polylineDecorator(this.emergencyRoute2Coordinates, {
        patterns: [
          {
            offset: '25%',
            repeat: 50,
            symbol: L.Symbol.arrowHead({
              pixelSize: 15,
              headAngle: 60,
              pathOptions: {
                fillOpacity: 0.9,
                weight: 0,
                color: '#0000FF'
              }
            })
          }
        ]
      }).addTo(map);
      
      console.log('[线路箭头] 已添加线路箭头装饰器');
    },
    
    // 切换路线示例组件的显示/隐藏
    toggleRouteExample() {
      this.showRouteExample = !this.showRouteExample;
    },
    
    // 处理线路选择变化
    handleRouteChange() {
      console.log('线路选择变化:', this.selectedRoute);
      
      // 定义所有线路数据
      const routeDataMap = {
        '通丰1号线': {
          originalRoute: [
        [41.82699179, 126.1758054],  // 1号塔
        [42.5691748, 125.6857459]  // 140号塔
      ],
          detourRoutes: [
            [
        [41.82699179, 126.1758054],  // 2号塔
        [41.78914913, 126.0039296]  // 59号塔
      ],
            [
        [41.78099556, 125.9464538],  // 1号塔
        [41.7901996, 126.005845]  // 29号塔
      ],
            [
        [41.78256078, 125.94552766000001],  // 1号塔
        [42.25107994066251, 125.82455263162291]  // 140号塔
      ],
            [
        [42.25187012, 125.8233723],  // 1号塔
        [42.49899402, 125.7522012]  // 90号塔
      ],
            [
        [42.5001350805555, 125.752244166666],  // 1号塔
        [42.569294266, 125.686965232]  // 47号塔
      ],
            [
        [42.748921037, 125.578943124],  // 1号塔
        [42.5691748, 125.6857459]  // 159号塔
            ]
        ],
        originalRouteConfig: {
          name: '通丰1号线',
          description: '杆塔：1号至140号',
          towerNames: ['1号塔', '140号塔']
        },
        detourRoutesConfig: [
          {
            name: '通桃线-分甲乙线',
            description: '杆塔：2号至59号',
            towerNames: ['2号塔', '59号塔']
          },
          {
            name: '长桃南北线',
            description: '杆塔：1号至29号',
            towerNames: ['1号塔', '29号塔']
          },
          {
            name: '长郑线',
            description: '杆塔：1号至140号',
            towerNames: ['1号塔', '140号塔']
          },
          {
            name: '郑曙线',
            description: '杆塔：1号至90号',
            towerNames: ['1号塔', '90号塔']
          },
          {
            name: '曙梅乙线',
            description: '杆塔：1号至47号',
            towerNames: ['1号塔', '47号塔']
          },
          {
            name: '东梅甲线',
            description: '杆塔：1号至159号',
            towerNames: ['1号塔', '159号塔']
          }
        ]
        },
        '通金线': {
          originalRoute: [
  [41.8267599, 126.175852],  // 1号塔
  [41.67377477, 125.9376053]  // 103号塔
],
          detourRoutes: [
            [
  [41.82699179, 126.1758054],  // 2号塔
  [41.78914913, 126.0039296]  // 59号塔
],
            [
  [41.78099556, 125.9464538],  // 1号塔
  [41.7901996, 126.005845]  // 29号塔
],
            [
  [41.7825390388889, 125.94498206666701],  // 1号塔
  [41.67386, 125.937188766667]  // 43号塔
],
            [
  [41.8267599, 126.175852],  // 1号塔
  [41.67377477, 125.9376053]  // 103号塔
            ]
  ],
  originalRouteConfig: {
    name: '原有线路：通金线',
    description: '杆塔：1号至103号',
    towerNames: ['1号塔', '103号塔']
  },
  detourRoutesConfig: [
    {
      name: '应急迂回线路：通桃线',
      description: '杆塔：2号至59号',
      towerNames: ['2号塔', '59号塔']
    },
    {
      name: '应急迂回线路：长桃南北线',
      description: '杆塔：1号至29号',
      towerNames: ['1号塔', '29号塔']
    },
    {
      name: '应急迂回线路：长金线',
      description: '杆塔：1号至43号',
      towerNames: ['1号塔', '43号塔']
    },
    {
      name: '应急迂回线路：通金线',
      description: '杆塔：1号至103号',
      towerNames: ['1号塔', '103号塔']
    }
  ]
        },
        '金集甲线': {
          originalRoute: [
  [41.669593888, 125.9328],  // 4号塔
  [41.203967087, 126.291721021]  // 164号塔
],
          detourRoutes: [
            [
  [41.37400002, 126.50100001],  // 1号塔
  [41.193582, 126.29512600000001]  // 72号塔
],
            [
  [41.37400002, 126.50100001],  // 1号塔
  [41.77813566, 126.08966329]  // 135号塔
],
            [
  [41.67603661005325, 125.93330486369449],  // 1号塔
  [41.776959712792795, 126.08508020318338]  // 73号塔
            ]
  ],
  originalRouteConfig: {
    name: '原有线路：金集甲线',
    description: '杆塔：4号至164号',
    towerNames: ['4号塔', '164号塔']
  },
  detourRoutesConfig: [
    {
      name: '应急迂回线路：云安线',
      description: '杆塔：1号至72号',
      towerNames: ['1号塔', '72号塔']
    },
    {
      name: '应急迂回线路：云水线',
      description: '杆塔：1号至135号',
      towerNames: ['1号塔', '135号塔']
    },
    {
      name: '应急迂回线路：金水甲线',
      description: '杆塔：1号至73号',
      towerNames: ['1号塔', '73号塔']
    }
  ]
        },
        '长郑线': {
          originalRoute: [
        [41.78256078, 125.94552766000001],  // 1号塔
        [42.25107994066251, 125.82455263162291]  // 140号塔
      ],
          detourRoutes: [
            [
        [41.780943496, 125.94568483100001],  // 1号塔
        [42.04933731, 125.757032241]  // 218号塔
      ],
            [
        [42.251307386, 125.82101946600001],  // 220kV郑家变
        [42.0493135805556, 125.75748983000001]  // 170号塔
            ]
      ],
        originalRouteConfig: {
          name: '原有线路：长郑线1',
          description: '杆塔：1号至140号',
          towerNames: ['1号塔', '140号塔']
        },
        detourRoutesConfig: [
          {
            name: '应急迂回线路：66kV长三线1',
            description: '杆塔：1号至218号，连接66kV三源浦变',
            towerNames: ['1号塔', '218号塔']
          },
          {
            name: '应急迂回线路：66kV郑三线1',
            description: '杆塔：郑家变至170号',
            towerNames: ['郑家变', '170号塔']
          }
        ]
        },
        '高梅线': {
          originalRoute: [
  [42.64947383, 126.1387708],  // 2号塔
  [42.5691748, 125.6857459]  // 179号塔
],
          detourRoutes: [
            [
  [42.650798796, 126.136986049],  // 1号塔
  [42.694693197, 126.029130112]  // 55号塔
],
            [
  [42.56751456, 125.68758700000001],  // 1号塔
  [42.6947226217513, 126.028744426719]  // 197号塔
],
            [
  [42.64924134, 126.137828959],  // 1号塔
  [42.748921037, 125.578943124]  // 159号塔
],
            [
  [42.748921037, 125.578943124],  // 1号塔
  [42.5691748, 125.6857459]  // 159号塔
            ]
  ],
  originalRouteConfig: {
    name: '原有线路：高梅线',
    description: '杆塔：2号至179号',
    towerNames: ['2号塔', '179号塔']
  },
  detourRoutesConfig: [
    {
      name: '应急迂回线路：高朝线-分甲乙线',
      description: '杆塔：1号至55号',
      towerNames: ['1号塔', '55号塔']
    },
    {
      name: '应急迂回线路：梅朝线',
      description: '杆塔：1号至197号',
      towerNames: ['1号塔', '197号塔']
    },
    {
      name: '应急迂回线路：高东线',
      description: '杆塔：1号至159号',
      towerNames: ['1号塔', '159号塔']
    },
    {
      name: '应急迂回线路：东梅甲线',
      description: '杆塔：1号至159号',
      towerNames: ['1号塔', '159号塔']
    }
  ]
        },
        '高东线': {
          originalRoute: [
  [42.64924134, 126.137828959],  // 1号塔
  [42.748921037, 125.578943124]  // 159号塔
],
          detourRoutes: [
            [
  [42.650798796, 126.136986049],  // 1号塔
  [42.694693197, 126.029130112]  // 55号塔
],
            [
  [42.56751456, 125.68758700000001],  // 1号塔
  [42.6947226217513, 126.028744426719]  // 197号塔
],
            [
  [42.64947383, 126.1387708],  // 2号塔
  [42.5691748, 125.6857459]  // 179号塔
],
            [
  [42.5691748, 125.6857459],  // 1号塔
  [42.748921037, 125.578943124]  // 159号塔
            ]
  ],
  originalRouteConfig: {
    name: '原有线路：高东线',
    description: '杆塔：1号至159号',
    towerNames: ['1号塔', '159号塔']
  },
  detourRoutesConfig: [
    {
      name: '应急迂回线路：高朝线-分甲乙线',
      description: '杆塔：1号至55号',
      towerNames: ['1号塔', '55号塔']
    },
    {
      name: '应急迂回线路：梅朝线',
      description: '杆塔：1号至197号',
      towerNames: ['1号塔', '197号塔']
    },
    {
      name: '应急迂回线路：高梅线',
      description: '杆塔：2号至179号',
      towerNames: ['2号塔', '179号塔']
    },
    {
      name: '应急迂回线路：东梅甲线',
      description: '杆塔：1号至159号',
      towerNames: ['1号塔', '159号塔']
    }
  ]
        }
      };

      // 将线路数据存储到 localStorage
      try {
       // localStorage.setItem('gisRouteData', JSON.stringify(routeDataMap));
        console.log('线路数据已存储到 localStorage');
      } catch (error) {
        console.error('存储线路数据到 localStorage 失败:', error);
      }

      // 从 localStorage 获取线路数据
      let storedRouteData = null;
      try {
        const storedData = localStorage.getItem('gisRouteData');
        if (storedData) {
          storedRouteData = JSON.parse(storedData);
          console.log('从 localStorage 成功获取线路数据');
        }
      } catch (error) {
        console.error('从 localStorage 获取线路数据失败:', error);
        // 如果获取失败，使用默认数据
        storedRouteData = routeDataMap;
      }

      // 如果 localStorage 中没有数据，使用默认数据
      if (!storedRouteData) {
        storedRouteData = routeDataMap;
        console.log('使用默认线路数据');
      }

      // 根据选择的线路处理数据
      if (this.selectedRoute && storedRouteData[this.selectedRoute]) {
        const routeData = storedRouteData[this.selectedRoute];
        
        console.log(`处理线路: ${this.selectedRoute}`, routeData);

        // 设置坐标数据
        this.originalRouteCoordinates = routeData.originalRoute;
        
        // 设置迂回线路坐标（如果存在）
        if (routeData.detourRoutes && routeData.detourRoutes.length > 0) {
          // 根据迂回线路数量设置对应的坐标变量
          routeData.detourRoutes.forEach((route, index) => {
            switch(index) {
              case 0:
                this.emergencyRoute1Coordinates = route;
                break;
              case 1:
                this.emergencyRoute2Coordinates = route;
                break;
              case 2:
                this.emergencyRoute3Coordinates = route;
                break;
              case 3:
                this.emergencyRoute4Coordinates = route;
                break;
              case 4:
                this.emergencyRoute5Coordinates = route;
                break;
              case 5:
                this.emergencyRoute6Coordinates = route;
                break;
            }
          });
        }

        // 渲染线路
        this.renderRoutes({
          originalRoute: routeData.originalRoute,
          detourRoutes: routeData.detourRoutes || [],
          originalRouteConfig: routeData.originalRouteConfig,
          detourRoutesConfig: routeData.detourRoutesConfig || []
        });
      } else {
        console.warn(`未找到线路数据: ${this.selectedRoute}`);
        this.showMessage(`未找到线路数据: ${this.selectedRoute}`, 'warning');
      }
    },
    
    // 显示新增线路弹出框
    showAddRouteDialog() {
      this.showRouteDialog = true;
      // 重置表单数据
      this.resetNewRouteData();
    },
    
    // 关闭新增线路弹出框
    closeAddRouteDialog() {
      this.showRouteDialog = false;
    },
    
    // 重置新增线路数据
    resetNewRouteData() {
      this.newRouteData = {
        originalRouteName: '',
        originalRoute: {
          start: { lat: null, lng: null },
          end: { lat: null, lng: null }
        },
        detourRoutes: [
          {
            name: '',
            start: { lat: null, lng: null },
            end: { lat: null, lng: null }
          }
        ]
      };
    },
    
    // 新增应急迂回线路
    addDetourRoute() {
      this.newRouteData.detourRoutes.push({
        name: '',
        start: { lat: null, lng: null },
        end: { lat: null, lng: null }
      });
    },
    
    // 删除应急迂回线路
    removeDetourRoute(index) {
      if (this.newRouteData.detourRoutes.length > 1) {
        this.newRouteData.detourRoutes.splice(index, 1);
      }
    },
    
    // 验证表单数据
    validateNewRouteData() {
      const data = this.newRouteData;
      
      // 验证原始线路名称
      if (!data.originalRouteName || data.originalRouteName.trim() === '') {
        this.showMessage('请输入原始线路名称', 'error');
        return false;
      }
      
      // 验证原始线路坐标
      if (!data.originalRoute.start.lat || !data.originalRoute.start.lng ||
          !data.originalRoute.end.lat || !data.originalRoute.end.lng) {
        this.showMessage('请完整填写原始线路的起点和终点坐标', 'error');
        return false;
      }
      
      // 验证应急迂回线路
      for (let i = 0; i < data.detourRoutes.length; i++) {
        const detour = data.detourRoutes[i];
        if (!detour.name || detour.name.trim() === '') {
          this.showMessage(`请输入第${i + 1}个应急迂回线路的名称`, 'error');
          return false;
        }
        
        if (!detour.start.lat || !detour.start.lng ||
            !detour.end.lat || !detour.end.lng) {
          this.showMessage(`请完整填写第${i + 1}个应急迂回线路的坐标`, 'error');
          return false;
        }
      }
      
      return true;
    },
    
    // 保存新线路
    async saveNewRoute() {
      // 验证数据
      if (!this.validateNewRouteData()) {
        return;
      }
      
      const data = this.newRouteData;
      const routeName = data.originalRouteName.trim();
      
      try {
        // 从 localStorage 获取现有数据
        let existingData = {};
        const storedData = localStorage.getItem('gisRouteData');
        if (storedData) {
          existingData = JSON.parse(storedData);
        }
        
        // 检查线路名称是否已存在
        if (existingData[routeName]) {
          const confirmed = confirm(`线路"${routeName}"已存在，是否覆盖？`);
          if (!confirmed) {
            return;
          }
        }
        
        // 构建新线路数据，严格按照标准JSON格式
        const newRouteEntry = {
          // 原始线路坐标 [纬度, 经度]
          originalRoute: [
            [data.originalRoute.start.lat, data.originalRoute.start.lng],
            [data.originalRoute.end.lat, data.originalRoute.end.lng]
          ],
          // 应急迂回线路坐标数组
          detourRoutes: data.detourRoutes.map(detour => [
            [detour.start.lat, detour.start.lng],
            [detour.end.lat, detour.end.lng]
          ]),
          // 原始线路配置
          originalRouteConfig: {
            name: routeName,
            description: `杆塔：起点至终点`,
            towerNames: ['起点', '终点']
          },
          // 应急迂回线路配置
          detourRoutesConfig: data.detourRoutes.map((detour, index) => ({
            name: detour.name,
            description: `杆塔：起点至终点`,
            towerNames: ['起点', '终点']
          }))
        };
        
        // 添加到现有数据中
        existingData[routeName] = newRouteEntry;
        
        // 保存到 localStorage
        localStorage.setItem('gisRouteData', JSON.stringify(existingData));
        
        // 更新路线选项
        this.routeOptions = Object.keys(existingData);
        
        // 关闭弹出框
        this.closeAddRouteDialog();
        
        // 显示成功消息
        this.showMessage(`线路"${routeName}"已成功保存`, 'success');
        
        console.log('新增线路成功:', routeName, newRouteEntry);
        console.log('生成的JSON结构:', JSON.stringify({[routeName]: newRouteEntry}, null, 2));
        
        // 自动选择新添加的线路
        this.selectedRoute = routeName;
        this.handleRouteChange();
        
      } catch (error) {
        console.error('保存新线路失败:', error);
        this.showMessage('保存线路失败: ' + error.message, 'error');
      }
    },
    
    // 初始化路线选项（修改后的方法）
    initRouteOptions() {
      console.log('开始初始化路线选项');
      
      // 首先定义默认的线路数据（与 handleRouteChange 中的数据保持一致）
      const defaultRouteDataMap = {
        '通丰1号线': {
          originalRoute: [
            [41.82699179, 126.1758054],  // 1号塔
            [42.5691748, 125.6857459]  // 140号塔
          ],
          detourRoutes: [
            [
              [41.82699179, 126.1758054],  // 2号塔
              [41.78914913, 126.0039296]  // 59号塔
            ],
            [
              [41.78099556, 125.9464538],  // 1号塔
              [41.7901996, 126.005845]  // 29号塔
            ],
            [
              [41.78256078, 125.94552766000001],  // 1号塔
              [42.25107994066251, 125.82455263162291]  // 140号塔
            ],
            [
              [42.25187012, 125.8233723],  // 1号塔
              [42.49899402, 125.7522012]  // 90号塔
            ],
            [
              [42.5001350805555, 125.752244166666],  // 1号塔
              [42.569294266, 125.686965232]  // 47号塔
            ],
            [
              [42.748921037, 125.578943124],  // 1号塔
              [42.5691748, 125.6857459]  // 159号塔
            ]
          ],
          originalRouteConfig: {
            name: '通丰1号线',
            description: '杆塔：1号至140号',
            towerNames: ['1号塔', '140号塔']
          },
          detourRoutesConfig: [
            {
              name: '通桃线-分甲乙线',
              description: '杆塔：2号至59号',
              towerNames: ['2号塔', '59号塔']
            },
            {
              name: '长桃南北线',
              description: '杆塔：1号至29号',
              towerNames: ['1号塔', '29号塔']
            },
            {
              name: '长郑线',
              description: '杆塔：1号至140号',
              towerNames: ['1号塔', '140号塔']
            },
            {
              name: '郑曙线',
              description: '杆塔：1号至90号',
              towerNames: ['1号塔', '90号塔']
            },
            {
              name: '曙梅乙线',
              description: '杆塔：1号至47号',
              towerNames: ['1号塔', '47号塔']
            },
            {
              name: '东梅甲线',
              description: '杆塔：1号至159号',
              towerNames: ['1号塔', '159号塔']
            }
          ]
        },
        // ... 其他默认线路数据
      };
      
      // 尝试从 localStorage 获取线路数据
      let routeDataMap = null;
      try {
        const storedData = localStorage.getItem('gisRouteData');
        if (storedData) {
          routeDataMap = JSON.parse(storedData);
          console.log('从 localStorage 成功获取线路数据进行初始化');
        }
      } catch (error) {
        console.error('从 localStorage 获取线路数据失败:', error);
      }
      
      // 如果没有从 localStorage 获取到数据，使用默认数据并存储到 localStorage
      if (!routeDataMap || Object.keys(routeDataMap).length === 0) {
        console.log('localStorage 中没有线路数据，使用默认数据并存储');
        routeDataMap = defaultRouteDataMap;
        
        // 将默认数据存储到 localStorage
        try {
          localStorage.setItem('gisRouteData', JSON.stringify(defaultRouteDataMap));
          console.log('默认线路数据已存储到 localStorage');
        } catch (error) {
          console.error('存储默认线路数据到 localStorage 失败:', error);
        }
      }
      
      // 从线路数据中提取所有 key 作为路线选项
      this.routeOptions = Object.keys(routeDataMap);
      console.log('初始化完成，路线选项:', this.routeOptions);
    },
    
    // 删除选中的线路
    deleteSelectedRoute() {
      if (!this.selectedRoute) {
        this.showMessage('请先选择要删除的线路', 'warning');
        return;
      }
      
      // 检查是否为系统默认线路
      const protectedRoutes = ['通丰1号线', '通金线', '金集甲线', '长郑线', '高梅线', '高东线'];
      if (protectedRoutes.includes(this.selectedRoute)) {
        const confirmed = confirm(`"${this.selectedRoute}" 是系统默认线路，确定要删除吗？`);
        if (!confirmed) {
          return;
        }
      }
      
      // 显示删除确认对话框
      this.routeToDelete = this.selectedRoute;
      this.showDeleteDialog = true;
    },
    
    // 关闭删除确认对话框
    closeDeleteDialog() {
      this.showDeleteDialog = false;
      this.routeToDelete = '';
    },
    
    // 确认删除线路
    async confirmDeleteRoute() {
      if (!this.routeToDelete) {
        return;
      }
      
      try {
        // 从 localStorage 获取现有数据
        const storedData = localStorage.getItem('gisRouteData');
        if (!storedData) {
          this.showMessage('没有找到线路数据', 'error');
          this.closeDeleteDialog();
          return;
        }
        
        let existingData = JSON.parse(storedData);
        
        // 检查要删除的线路是否存在
        if (!existingData[this.routeToDelete]) {
          this.showMessage(`线路"${this.routeToDelete}"不存在`, 'error');
          this.closeDeleteDialog();
          return;
        }
        
        // 删除线路数据
        delete existingData[this.routeToDelete];
        
        // 保存更新后的数据到 localStorage
        localStorage.setItem('gisRouteData', JSON.stringify(existingData));
        
        // 更新路线选项列表
        this.routeOptions = Object.keys(existingData);
        
        // 如果删除的是当前选中的线路，清空选择并清除地图上的线路
        if (this.selectedRoute === this.routeToDelete) {
          this.selectedRoute = '';
          this.clearAllRoutes();
        }
        
        // 关闭删除确认对话框
        this.closeDeleteDialog();
        
        // 显示成功消息
        this.showMessage(`线路"${this.routeToDelete}"已成功删除`, 'success');
        
        console.log('删除线路成功:', this.routeToDelete);
        console.log('剩余线路:', this.routeOptions);
        
      } catch (error) {
        console.error('删除线路失败:', error);
        this.showMessage('删除线路失败: ' + error.message, 'error');
        this.closeDeleteDialog();
      }
    },
    
    // 清除地图上的所有线路
    clearAllRoutes() {
      try {
        // 清除线路数据
        this.routes = [];
        
        // 清除箭头装饰器
        if (this.routeDecorators) {
          const map = this.$refs.myMap.mapObject;
          this.routeDecorators.forEach(decorator => {
            map.removeLayer(decorator);
          });
          this.routeDecorators = [];
        }
        
        // 清除坐标数据
        this.originalRouteCoordinates = [];
        this.emergencyRoute1Coordinates = [];
        this.emergencyRoute2Coordinates = [];
        this.emergencyRoute3Coordinates = [];
        this.emergencyRoute4Coordinates = [];
        this.emergencyRoute5Coordinates = [];
        this.emergencyRoute6Coordinates = [];
        this.emergencyRoute7Coordinates = [];
        this.emergencyRoute8Coordinates = [];
        
        console.log('已清除地图上的所有线路');
      } catch (error) {
        console.error('清除地图线路失败:', error);
      }
    },
    
    // 批量删除线路（可选功能）
    showBatchDeleteDialog() {
      // 可以扩展为批量删除功能
      this.showMessage('批量删除功能开发中...', 'info');
    },
    
    // 重置到默认线路（可选功能）
    resetToDefaultRoutes() {
      const confirmed = confirm('确定要重置为默认线路吗？这将删除所有自定义线路！');
      if (!confirmed) {
        return;
      }
      
      try {
        // 清除现有数据
        localStorage.removeItem('gisRouteData');
        
        // 重新初始化默认数据
        this.initRouteOptions();
        
        // 清空当前选择
        this.selectedRoute = '';
        this.clearAllRoutes();
        
        this.showMessage('已重置为默认线路', 'success');
      } catch (error) {
        console.error('重置默认线路失败:', error);
        this.showMessage('重置失败: ' + error.message, 'error');
      }
    },
  },
  mounted() {
    
    // 从本地存储加载离线模式设置
    console.log('mounted');
    const savedOfflineMode = localStorage.getItem('gisMapOfflineMode');
    if (savedOfflineMode === 'true') {
      this.forceOfflineMode = true;
    }
    
    // 创建塔杆图标
    this.createTowerIcon();
    
    // 初始化网络状态监听
    window.addEventListener('online', this.updateNetworkStatus);
    window.addEventListener('offline', this.updateNetworkStatus);
    
    // 启动定期网络检测
    this.networkCheckTimer = setInterval(() => {
      this.checkNetworkConnection();
    }, 30000); // 每30秒检测一次
    
    // 立即执行一次网络检测
    this.checkNetworkConnection();
    
    // 从localStorage 的key 为 "渲染" 的对象中，拿到 "故障定位" —> "落点区段" —> "前一个杆塔" -> "坐标"
    let previousTowerCoordinates = '';
    let nextTowerCoordinates = '';
    let originalRouteName = '';
    let previousTowerName = '';
    let nextTowerName = '';
    const renderData = localStorage.getItem('渲染');
    if (renderData) {
      const renderDataObj = JSON.parse(renderData);
      const faultLocation = renderDataObj.故障定位;
      const pointSection = faultLocation.落点区段;
      previousTowerCoordinates = pointSection.前一个杆塔.坐标;
      console.log(previousTowerCoordinates);
      nextTowerCoordinates = pointSection.后一个杆塔.坐标;
      console.log(nextTowerCoordinates);
      originalRouteName = renderDataObj.线路信息.线路名称;
      console.log(originalRouteName);
      previousTowerName = pointSection.前一个杆塔.杆塔名称;
      console.log(previousTowerName);
      nextTowerName = pointSection.后一个杆塔.杆塔名称;
      console.log(nextTowerName);
    }
    // 组件挂载后初始化离线地图
    this.$nextTick(() => {
      this.initOfflineMap();
      // 加载数据
      this.fetchPoints();
      
      // 处理从localStorage获取的坐标数据
      if (previousTowerCoordinates && nextTowerCoordinates) {
        // 将坐标字符串转换为数组形式
        // 原始格式: "(125.86386818000001,41.88676262)"
        const parsePreviousTower = previousTowerCoordinates.replace(/[()]/g, '').split(',');
        const parseNextTower = nextTowerCoordinates.replace(/[()]/g, '').split(',');
        
        // 注意：坐标格式需要转换为[纬度, 经度]的形式
        const previousTower = [parseFloat(parsePreviousTower[1]), parseFloat(parsePreviousTower[0])];
        const nextTower = [parseFloat(parseNextTower[1]), parseFloat(parseNextTower[0])];
        
        console.log('转换后的前一个杆塔坐标:', previousTower);
        console.log('转换后的后一个杆塔坐标:', nextTower);
        
        // 使用转换后的坐标初始化线路
        this.originalRouteCoordinates = [
          previousTower,  // 前一个杆塔
          nextTower       // 后一个杆塔
        ];
      } else {
        // 如果没有获取到坐标，使用默认值
        this.originalRouteCoordinates = [
          [41.78256078, 125.94552766000001],  // 1号塔
          [42.25107994066251, 125.82455263162291]  // 140号塔
        ];
      }
      // this.emergencyRoute1Coordinates= [
      //   [41.780943496, 125.94568483100001],  // 1号塔
      //   [42.04933731, 125.757032241]  // 218号塔
      // ],
      // this.emergencyRoute2Coordinates= [
      //   [42.251307386, 125.82101946600001],  // 220kV郑家变
      //   [42.0493135805556, 125.75748983000001]  // 170号塔
      // ],
      this.renderRoutes({
        originalRoute: this.originalRouteCoordinates,
        detourRoutes: [],
        originalRouteConfig: {
          name: originalRouteName,
          description: '杆塔异常',
          towerNames: [previousTowerName, nextTowerName]
        },
        detourRoutesConfig: [
          // {
          //   name: '应急迂回线路：66kV长三线1',
          //   description: '杆塔：1号至218号，连接66kV三源浦变',
          //   towerNames: ['1号塔', '218号塔']
          // },
          // {
          //   name: '应急迂回线路：66kV郑三线1',
          //   description: '杆塔：郑家变至170号',
          //   towerNames: ['郑家变', '170号塔']
          // }
        ]
      });
      
      // 初始化线路
      // this.originalRouteCoordinates= [
      //   [41.78256078, 125.94552766000001],  // 1号塔
      //   [42.25107994066251, 125.82455263162291]  // 140号塔
      // ],
      // this.emergencyRoute1Coordinates= [
      //   [41.780943496, 125.94568483100001],  // 1号塔
      //   [42.04933731, 125.757032241]  // 218号塔
      // ],
      // this.emergencyRoute2Coordinates= [
      //   [42.251307386, 125.82101946600001],  // 220kV郑家变
      //   [42.0493135805556, 125.75748983000001]  // 170号塔
      // ],
      // this.emergencyRoute3Coordinates= [
      //   [52.251307386, 135.82101946600001],  // 220kV郑家变
      //   [52.0493135805556, 135.75748983000001]  // 170号塔
      // ],
      // this.emergencyRoute4Coordinates= [
      //   [42.251307386, 125.82101946600001],  // 220kV郑家变
      //   [42.0493135805556, 125.75748983000001]  // 170号塔
      // ],
      // this.emergencyRoute5Coordinates= [
      //   [42.251307386, 125.82101946600001],  // 220kV郑家变
      //   [42.0493135805556, 125.75748983000001]  // 170号塔
      // ],
      // this.emergencyRoute6Coordinates= [
      //   [42.251307386, 125.82101946600001],  // 220kV郑家变
      //   [42.0493135805556, 125.75748983000001]  // 170号塔
      // ],
      // 
      // emergencyRoute7Coordinates: [
      //   [42.251307386, 125.82101946600001],  // 220kV郑家变
      //   [42.0493135805556, 125.75748983000001]  // 170号塔
      // ],
      // emergencyRoute8Coordinates: [
      //   [42.251307386, 125.82101946600001],  // 220kV郑家变
      //   [42.0493135805556, 125.75748983000001]  // 170号塔
      // ],
      // 
      // 
      // // 自定义塔杆图标
      // towerIcon: null,
      // 
      // // 控制路线示例组件的显示/隐藏
      // showRouteExample: false,
      
      // 初始化线路
      // this.originalRouteCoordinates = [
      //   [41.82699179, 126.1758054],  // 1号塔
      //   [42.5691748, 125.6857459]  // 140号塔
      // ],
      // this.emergencyRoute1Coordinates = [
      //   [41.82699179, 126.1758054],  // 2号塔
      //   [41.78914913, 126.0039296]  // 59号塔
      // ],
      // this.emergencyRoute2Coordinates = [
      //   [41.78099556, 125.9464538],  // 1号塔
      //   [41.7901996, 126.005845]  // 29号塔
      // ],
      // this.emergencyRoute3Coordinates = [
      //   [41.78256078, 125.94552766000001],  // 1号塔
      //   [42.25107994066251, 125.82455263162291]  // 140号塔
      // ],
      // this.emergencyRoute4Coordinates = [
      //   [42.25187012, 125.8233723],  // 1号塔
      //   [42.49899402, 125.7522012]  // 90号塔
      // ],
      // this.emergencyRoute5Coordinates = [
      //   [42.5001350805555, 125.752244166666],  // 1号塔
      //   [42.569294266, 125.686965232]  // 47号塔
      // ],
      // this.emergencyRoute6Coordinates = [
      //   [42.748921037, 125.578943124],  // 1号塔
      //   [42.5691748, 125.6857459]  // 159号塔
      // ],
      // this.renderRoutes({
      //   originalRoute: this.originalRouteCoordinates,
      //   detourRoutes: [
      //     this.emergencyRoute1Coordinates, 
      //     this.emergencyRoute2Coordinates, 
      //     this.emergencyRoute3Coordinates,
      //     this.emergencyRoute4Coordinates,
      //     this.emergencyRoute5Coordinates,
      //     this.emergencyRoute6Coordinates
      //   ],
      //   originalRouteConfig: {
      //     name: '通丰1号线',
      //     description: '杆塔：1号至140号',
      //     towerNames: ['1号塔', '140号塔']
      //   },
      //   detourRoutesConfig: [
      //     {
      //       name: '通桃线-分甲乙线',
      //       description: '杆塔：2号至59号',
      //       towerNames: ['2号塔', '59号塔']
      //     },
      //     {
      //       name: '长桃南北线',
      //       description: '杆塔：1号至29号',
      //       towerNames: ['1号塔', '29号塔']
      //     },
      //     {
      //       name: '长郑线',
      //       description: '杆塔：1号至140号',
      //       towerNames: ['1号塔', '140号塔']
      //     },
      //     {
      //       name: '郑曙线',
      //       description: '杆塔：1号至90号',
      //       towerNames: ['1号塔', '90号塔']
      //     },
      //     {
      //       name: '曙梅乙线',
      //       description: '杆塔：1号至47号',
      //       towerNames: ['1号塔', '47号塔']
      //     },
      //     {
      //       name: '东梅甲线',
      //       description: '杆塔：1号至159号',
      //       towerNames: ['1号塔', '159号塔']
      //     }
      //   ]
      // });


      
    });


    let routeDataMap = null;
    try {
      const storedData = localStorage.getItem('gisRouteData');
      if (storedData) {
        routeDataMap = JSON.parse(storedData);
        console.log('从 localStorage 成功获取线路数据进行初始化');
      }
    } catch (error) {
      console.error('从 localStorage 获取线路数据失败:', error);
    }
    
    // 如果没有从 localStorage 获取到数据，使用默认数据并存储到 localStorage
    if (!routeDataMap || Object.keys(routeDataMap).length === 0) {
      // console.log('localStorage 中没有线路数据，使用默认数据并存储');
      // routeDataMap = defaultRouteDataMap;
      
      // 将默认数据存储到 localStorage
      try {
        // // localStorage.setItem('gisRouteData', JSON.stringify(defaultRouteDataMap));
        // console.log('默认线路数据已存储到 localStorage');
      } catch (error) {
        console.error('存储默认线路数据到 localStorage 失败:', error);
      }
    }
    
    // 从线路数据中提取所有 key 作为路线选项
    this.routeOptions = Object.keys(routeDataMap);
    console.log('初始化完成，路线选项:', this.routeOptions);

    // 初始化路线选项
    this.initRouteOptions();
  },
  beforeDestroy() {
    // 清除事件监听器
    window.removeEventListener('online', this.updateNetworkStatus);
    window.removeEventListener('offline', this.updateNetworkStatus);
    
    // 清除定时器
    if (this.networkCheckTimer) {
      clearInterval(this.networkCheckTimer);
    }
  }
};
</script>

<style scoped>
.map-container {
  height: calc(100vh - 20px);
  width: 100%;
  position: relative;
}

.map-controls {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1000;
  background: white;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 1px 5px rgba(0,0,0,0.2);
  min-width: 200px;
}

.map-message {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  padding: 10px 20px;
  border-radius: 4px;
  color: white;
  font-weight: bold;
  z-index: 2000;
  box-shadow: 0 2px 8px rgba(0,0,0,0.3);
  animation: fade-in-out 3s forwards;
}

.map-message.success {
  background-color: rgba(76, 175, 80, 0.9);
}

.map-message.error {
  background-color: rgba(244, 67, 54, 0.9);
}

.map-message.warning {
  background-color: rgba(255, 152, 0, 0.9);
}

.map-message.info {
  background-color: rgba(33, 150, 243, 0.9);
}

@keyframes fade-in-out {
  0% { opacity: 0; }
  15% { opacity: 1; }
  85% { opacity: 1; }
  100% { opacity: 0; }
}

.network-status {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 12px;
  z-index: 1000;
  background-color: white;
  box-shadow: 0 1px 5px rgba(0,0,0,0.2);
  display: flex;
  align-items: center;
  flex-direction: column;
  min-width: 120px;
}

.network-status span {
  margin-bottom: 5px;
  font-weight: bold;
}

.network-toggle {
  background-color: #f0f0f0;
  border: none;
  padding: 4px 8px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 11px;
  transition: background-color 0.2s;
  white-space: nowrap;
}

.network-toggle:hover {
  background-color: #e0e0e0;
}

.network-status.online {
  color: #4CAF50;
}

.network-status.offline {
  color: #F44336;
}

.control-buttons {
  display: flex;
  gap: 10px;
  margin-top: 5px;
}

.zoom-settings {
  margin: 10px 0;
  padding: 8px;
  background-color: #f9f9f9;
  border-radius: 4px;
  font-size: 14px;
}

.setting-label {
  font-weight: bold;
  margin-bottom: 5px;
  color: #333;
}

.zoom-range {
  display: flex;
  align-items: center;
  margin: 5px 0;
}

.zoom-range span {
  width: 25px;
  text-align: center;
}

.zoom-range input {
  flex: 1;
  margin-left: 5px;
}

.zoom-info {
  font-size: 12px;
  color: #666;
  margin-top: 4px;
}

.action-button {
  padding: 8px 12px;
  border: none;
  border-radius: 4px;
  background-color: #f0f0f0;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s;
}

.action-button:hover:not(:disabled) {
  background-color: #e0e0e0;
}

.action-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.primary {
  background-color: #4CAF50;
  color: white;
}

.primary:hover {
  background-color: #3e8e41;
}

.upload-button {
  display: inline-block;
  padding: 8px 12px;
  background-color: #f0f0f0;
  border-radius: 4px;
  cursor: pointer;
  text-align: center;
}

.upload-button:hover {
  background-color: #e0e0e0;
}

.cache-hint {
  color: #ff6600;
  margin-bottom: 8px;
  font-size: 14px;
}

.progress-bar {
  height: 20px;
  background-color: #f0f0f0;
  border-radius: 4px;
  margin: 5px 0;
  overflow: hidden;
}

.progress-value {
  height: 100%;
  background-color: #4CAF50;
  transition: width 0.3s;
}

.advanced-options {
  margin-top: 15px;
  padding-top: 10px;
  border-top: 1px solid #ddd;
}

.warning {
  background-color: #FF9800;
  color: white;
}

.warning:hover {
  background-color: #F57C00;
}

.danger {
  background-color: #F44336;
  color: white;
}

.danger:hover {
  background-color: #D32F2F;
}

.info {
  background-color: #2196F3;
  color: white;
}

.info:hover {
  background-color: #0b7dda;
}

.cache-diagnosis {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.2);
  padding: 20px;
  max-width: 500px;
  width: 80%;
  z-index: 2000;
  overflow-y: auto;
  max-height: 80vh;
}

.cache-diagnosis h3 {
  margin-top: 0;
  color: #2196F3;
  border-bottom: 1px solid #eee;
  padding-bottom: 10px;
}

.cache-diagnosis ul {
  padding-left: 20px;
}

.cache-diagnosis .close-btn {
  background-color: #f0f0f0;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  display: block;
  margin: 15px auto 0;
}

.cache-diagnosis .close-btn:hover {
  background-color: #e0e0e0;
}

.zoom-info-display {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1000;
  background: white;
  padding: 5px 10px;
  border-radius: 4px;
  box-shadow: 0 1px 5px rgba(0,0,0,0.2);
  min-width: 120px;
  text-align: right;
}

.zoom-info-display .zoom-level {
  font-weight: bold;
}

.cache-toggle-button {
  position: absolute;
  top: 50px;
  right: 10px;
  z-index: 1000;
  background: white;
  padding: 5px 10px;
  border-radius: 4px;
  box-shadow: 0 1px 5px rgba(0,0,0,0.2);
  border: none;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s;
}

.cache-toggle-button:hover {
  background-color: #f0f0f0;
}

.route-legend {
  position: absolute;
  bottom: 20px;
  right: 10px;
  z-index: 1000;
  background: white;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 1px 5px rgba(0,0,0,0.2);
  min-width: 200px;
}

.route-legend h4 {
  margin: 0 0 10px 0;
  font-size: 14px;
  text-align: center;
}

.legend-item {
  display: flex;
  align-items: center;
  margin-bottom: 5px;
}

.color-box {
  display: inline-block;
  width: 15px;
  height: 5px;
  margin-right: 8px;
}

/* 塔杆图标样式 */
.tower-icon-container {
  background: transparent;
}

.tower-icon-container svg {
  filter: drop-shadow(0px 2px 2px rgba(0, 0, 0, 0.5));
}

.tower-icon {
  width: 20px;
  height: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.tower-pole {
  display: block;
  width: 6px;
  height: 16px;
  background-color: #333;
  position: relative;
}

.tower-pole:before, .tower-pole:after {
  content: '';
  position: absolute;
  background-color: #333;
}

.tower-pole:before {
  width: 12px;
  height: 2px;
  top: 3px;
  left: -3px;
}

.tower-pole:after {
  width: 12px;
  height: 2px;
  top: 10px;
  left: -3px;
}

/* 图例中的小塔杆图标 */
.tower-legend {
  margin-top: 8px;
}

.small-tower-icon {
  width: 12px;
  height: 16px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-right: 8px;
}

.small-tower-icon svg {
  filter: drop-shadow(0px 1px 1px rgba(0, 0, 0, 0.3));
}

.small-tower-pole {
  display: block;
  width: 4px;
  height: 12px;
  background-color: #333;
  position: relative;
}

.small-tower-pole:before, .small-tower-pole:after {
  content: '';
  position: absolute;
  background-color: #333;
}

.small-tower-pole:before {
  width: 8px;
  height: 1.5px;
  top: 2.5px;
  left: -2px;
}

.small-tower-pole:after {
  width: 8px;
  height: 1.5px;
  top: 7.5px;
  left: -2px;
}

.route-example-toggle {
  position: absolute;
  top: 50px;
  left: 10px;
  padding: 5px 10px;
  background-color: white;
  border: none;
  border-radius: 4px;
  box-shadow: 0 1px 5px rgba(0,0,0,0.2);
  cursor: pointer;
  font-size: 14px;
  z-index: 1000;
}

.route-example-toggle:hover {
  background-color: #f0f0f0;
}

.map-controls-toggle {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  background: white;
  padding: 5px 10px;
  border-radius: 4px;
  box-shadow: 0 1px 5px rgba(0,0,0,0.2);
  border: none;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s;
}

.map-controls-toggle:hover {
  background-color: #f0f0f0;
}

.route-selector {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 1000;
  background: white;
  padding: 5px 10px;
  border-radius: 4px;
  box-shadow: 0 1px 5px rgba(0,0,0,0.2);
  min-width: 150px;
}

.route-select {
  width: 100%;
  padding: 5px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.route-selector {
  display: flex;
  align-items: center;
  gap: 8px;
}

.add-route-btn {
  padding: 5px 12px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  transition: background-color 0.3s;
}

.add-route-btn:hover {
  background-color: #45a049;
}

/* 弹出框样式 */
.route-dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 10000;
  display: flex;
  justify-content: center;
  align-items: center;
}

.route-dialog {
  background: white;
  border-radius: 8px;
  padding: 20px;
  max-width: 600px;
  max-height: 80vh;
  overflow-y: auto;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  width: 90%;
}

.route-dialog h3 {
  margin-top: 0;
  margin-bottom: 20px;
  text-align: center;
  color: #333;
}

.route-section {
  border: 1px solid #ddd;
  border-radius: 6px;
  padding: 15px;
  margin-bottom: 15px;
  background-color: #f9f9f9;
}

.route-header {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  gap: 10px;
}

.route-label {
  font-weight: bold;
  min-width: 120px;
  color: #333;
}

.route-input {
  flex: 1;
  padding: 6px 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 14px;
}

.delete-route-btn {
  background-color: #f44336;
  color: white;
  border: none;
  border-radius: 50%;
  width: 24px;
  height: 24px;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.delete-route-btn:hover {
  background-color: #d32f2f;
}

.coordinate-row {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  gap: 8px;
}

.coord-label {
  font-size: 12px;
  color: #666;
  min-width: 40px;
}

.coord-input {
  flex: 1;
  padding: 4px 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 12px;
}

.add-detour-section {
  text-align: center;
  margin: 20px 0;
}

.add-detour-btn {
  background-color: #2196F3;
  color: white;
  border: none;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  cursor: pointer;
  font-size: 20px;
  font-weight: bold;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto;
}

.add-detour-btn:hover {
  background-color: #1976D2;
}

.dialog-actions {
  display: flex;
  justify-content: center;
  gap: 15px;
  margin-top: 20px;
  border-top: 1px solid #eee;
  padding-top: 20px;
}

.cancel-btn, .save-btn {
  padding: 10px 25px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  font-weight: bold;
  transition: background-color 0.3s;
}

.cancel-btn {
  background-color: #f0f0f0;
  color: #333;
}

.cancel-btn:hover {
  background-color: #e0e0e0;
}

.save-btn {
  background-color: #4CAF50;
  color: white;
}

.save-btn:hover {
  background-color: #45a049;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .route-dialog {
    width: 95%;
    margin: 10px;
    max-height: 90vh;
  }
  
  .coordinate-row {
    flex-direction: column;
    align-items: stretch;
  }
  
  .coord-label {
    min-width: auto;
  }
}

.route-selector {
  display: flex;
  align-items: center;
  gap: 8px;
}

.add-route-btn {
  padding: 5px 12px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  transition: background-color 0.3s;
}

.add-route-btn:hover {
  background-color: #45a049;
}

.delete-route-btn {
  padding: 5px 12px;
  background-color: #f44336;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  transition: background-color 0.3s;
}

.delete-route-btn:hover:not(.disabled) {
  background-color: #d32f2f;
}

.delete-route-btn.disabled {
  background-color: #ccc;
  cursor: not-allowed;
  opacity: 0.6;
}

.delete-route-btn:disabled {
  background-color: #ccc;
  cursor: not-allowed;
  opacity: 0.6;
}

/* 删除确认对话框样式 */
.delete-dialog {
  background: white;
  border-radius: 8px;
  padding: 25px;
  max-width: 400px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  text-align: center;
}

.delete-dialog h3 {
  margin-top: 0;
  margin-bottom: 15px;
  color: #f44336;
  font-size: 18px;
}

.delete-dialog p {
  margin: 10px 0;
  color: #333;
  line-height: 1.5;
}

.warning-text {
  color: #ff9800 !important;
  font-weight: bold;
  font-size: 14px;
}

.confirm-delete-btn {
  background-color: #f44336;
  color: white;
}

.confirm-delete-btn:hover {
  background-color: #d32f2f;
}

/* 增强按钮组的响应式设计 */
@media (max-width: 768px) {
  .route-selector {
    flex-direction: column;
    align-items: stretch;
    gap: 5px;
    min-width: 120px;
  }
  
  .route-select {
    margin-bottom: 5px;
  }
  
  .add-route-btn,
  .delete-route-btn {
    width: 100%;
    padding: 8px 12px;
    font-size: 14px;
  }
  
  .delete-dialog {
    margin: 20px;
    max-width: 90%;
  }
}

/* 添加动画效果 */
.delete-route-btn {
  position: relative;
  overflow: hidden;
}

.delete-route-btn:not(.disabled):active {
  transform: scale(0.98);
}

/* 提示动画 */
@keyframes shake {
  0%, 20%, 50%, 80%, 100% {
    transform: translateX(0);
  }
  10%, 30%, 70%, 90% {
    transform: translateX(-2px);
  }
  40%, 60% {
    transform: translateX(2px);
  }
}

.delete-route-btn.shake {
  animation: shake 0.5s ease-in-out;
}
</style>
